@@ -4,7 +4,7 @@ import { Label } from '@/components/ui/label'
44import { Input } from '@/components/ui/input'
55import { PasswordInput } from '@/components/ui/password-input'
66import { Button } from '@/components/ui/button'
7- import { useEffect } from 'react'
7+ import { useEffect , useState } from 'react'
88import { z } from 'zod'
99import { useForm } from 'react-hook-form'
1010import { zodResolver } from '@hookform/resolvers/zod'
@@ -43,6 +43,7 @@ const notificationSettingsSchema = z.object({
4343
4444type NotificationSettingsForm = z . infer < typeof notificationSettingsSchema >
4545
46+
4647export default function NotificationSettings ( ) {
4748 const { t } = useTranslation ( )
4849
@@ -396,18 +397,47 @@ export default function NotificationSettings() {
396397 < FormField
397398 control = { form . control }
398399 name = "notification_settings.telegram_admin_id"
399- render = { ( { field } ) => (
400- < FormControl >
401- < Input
402- type = "number"
403- { ...field }
404- value = { field . value || '' }
405- onChange = { ( e ) => field . onChange ( e . target . value ? parseInt ( e . target . value ) : undefined ) }
406- className = "w-full"
407- placeholder = "123456789"
408- />
409- </ FormControl >
410- ) }
400+ render = { ( { field } ) => {
401+ const [ inputValue , setInputValue ] = useState ( field . value ?. toString ( ) ?? '' ) ;
402+
403+ // Sync input value when field value changes (e.g., from form reset)
404+ useEffect ( ( ) => {
405+ setInputValue ( field . value ?. toString ( ) ?? '' ) ;
406+ } , [ field . value ] ) ;
407+
408+ return (
409+ < FormControl >
410+ < Input
411+ type = "text"
412+ name = { field . name }
413+ ref = { field . ref }
414+ value = { inputValue }
415+ onChange = { ( e ) => {
416+ const value = e . target . value ;
417+ setInputValue ( value ) ;
418+
419+ // Update form value for valid inputs or empty
420+ if ( value === '' ) {
421+ field . onChange ( undefined ) ;
422+ } else if ( / ^ - ? \d + $ / . test ( value ) ) {
423+ field . onChange ( parseInt ( value ) ) ;
424+ }
425+ // Keep invalid input in display but don't update form
426+ } }
427+ onBlur = { ( ) => {
428+ // On blur, ensure the display matches the form value
429+ // If current input is invalid, reset display to form value
430+ if ( inputValue !== '' && ! / ^ - ? \d + $ / . test ( inputValue ) ) {
431+ setInputValue ( field . value ?. toString ( ) ?? '' ) ;
432+ }
433+ field . onBlur ( ) ;
434+ } }
435+ className = "w-full"
436+ placeholder = "123456789"
437+ />
438+ </ FormControl >
439+ ) ;
440+ } }
411441 />
412442 </ div >
413443
@@ -419,18 +449,47 @@ export default function NotificationSettings() {
419449 < FormField
420450 control = { form . control }
421451 name = "notification_settings.telegram_channel_id"
422- render = { ( { field } ) => (
423- < FormControl >
424- < Input
425- type = "number"
426- { ...field }
427- value = { field . value || '' }
428- onChange = { ( e ) => field . onChange ( e . target . value ? parseInt ( e . target . value ) : undefined ) }
429- className = "w-full"
430- placeholder = "-1001234567890"
431- />
432- </ FormControl >
433- ) }
452+ render = { ( { field } ) => {
453+ const [ inputValue , setInputValue ] = useState ( field . value ?. toString ( ) ?? '' ) ;
454+
455+ // Sync input value when field value changes (e.g., from form reset)
456+ useEffect ( ( ) => {
457+ setInputValue ( field . value ?. toString ( ) ?? '' ) ;
458+ } , [ field . value ] ) ;
459+
460+ return (
461+ < FormControl >
462+ < Input
463+ type = "text"
464+ name = { field . name }
465+ ref = { field . ref }
466+ value = { inputValue }
467+ onChange = { ( e ) => {
468+ const value = e . target . value ;
469+ setInputValue ( value ) ;
470+
471+ // Update form value for valid inputs or empty
472+ if ( value === '' ) {
473+ field . onChange ( undefined ) ;
474+ } else if ( / ^ - ? \d + $ / . test ( value ) ) {
475+ field . onChange ( parseInt ( value ) ) ;
476+ }
477+ // Keep invalid input in display but don't update form
478+ } }
479+ onBlur = { ( ) => {
480+ // On blur, ensure the display matches the form value
481+ // If current input is invalid, reset display to form value
482+ if ( inputValue !== '' && ! / ^ - ? \d + $ / . test ( inputValue ) ) {
483+ setInputValue ( field . value ?. toString ( ) ?? '' ) ;
484+ }
485+ field . onBlur ( ) ;
486+ } }
487+ className = "w-full"
488+ placeholder = "-1001234567890"
489+ />
490+ </ FormControl >
491+ ) ;
492+ } }
434493 />
435494 </ div >
436495
@@ -442,18 +501,47 @@ export default function NotificationSettings() {
442501 < FormField
443502 control = { form . control }
444503 name = "notification_settings.telegram_topic_id"
445- render = { ( { field } ) => (
446- < FormControl >
447- < Input
448- type = "number"
449- { ...field }
450- value = { field . value || '' }
451- onChange = { ( e ) => field . onChange ( e . target . value ? parseInt ( e . target . value ) : undefined ) }
452- className = "w-full"
453- placeholder = "123"
454- />
455- </ FormControl >
456- ) }
504+ render = { ( { field } ) => {
505+ const [ inputValue , setInputValue ] = useState ( field . value ?. toString ( ) ?? '' ) ;
506+
507+ // Sync input value when field value changes (e.g., from form reset)
508+ useEffect ( ( ) => {
509+ setInputValue ( field . value ?. toString ( ) ?? '' ) ;
510+ } , [ field . value ] ) ;
511+
512+ return (
513+ < FormControl >
514+ < Input
515+ type = "text"
516+ name = { field . name }
517+ ref = { field . ref }
518+ value = { inputValue }
519+ onChange = { ( e ) => {
520+ const value = e . target . value ;
521+ setInputValue ( value ) ;
522+
523+ // Update form value for valid inputs or empty
524+ if ( value === '' ) {
525+ field . onChange ( undefined ) ;
526+ } else if ( / ^ - ? \d + $ / . test ( value ) ) {
527+ field . onChange ( parseInt ( value ) ) ;
528+ }
529+ // Keep invalid input in display but don't update form
530+ } }
531+ onBlur = { ( ) => {
532+ // On blur, ensure the display matches the form value
533+ // If current input is invalid, reset display to form value
534+ if ( inputValue !== '' && ! / ^ - ? \d + $ / . test ( inputValue ) ) {
535+ setInputValue ( field . value ?. toString ( ) ?? '' ) ;
536+ }
537+ field . onBlur ( ) ;
538+ } }
539+ className = "w-full"
540+ placeholder = "123"
541+ />
542+ </ FormControl >
543+ ) ;
544+ } }
457545 />
458546 </ div >
459547 </ div >
@@ -550,12 +638,24 @@ export default function NotificationSettings() {
550638 name = "notification_settings.max_retries"
551639 render = { ( { field } ) => (
552640 < FormControl >
553- < Input
554- type = "number"
555- min = "1"
641+ < Input
642+ type = "number"
643+ min = "1"
556644 max = "10"
557- { ...field }
558- onChange = { ( e ) => field . onChange ( parseInt ( e . target . value ) ) }
645+ name = { field . name }
646+ ref = { field . ref }
647+ value = { field . value ?? '' }
648+ onChange = { ( e ) => {
649+ const value = e . target . value ;
650+ // Allow typing any characters, but only set valid positive numbers or empty (defaults to 3)
651+ if ( value === '' ) {
652+ field . onChange ( 3 ) ;
653+ } else if ( / ^ \d + $ / . test ( value ) ) {
654+ field . onChange ( parseInt ( value ) ) ;
655+ }
656+ // Ignore invalid input
657+ } }
658+ onBlur = { field . onBlur }
559659 className = "w-full"
560660 placeholder = "3"
561661 />
0 commit comments