/* eslint-disable promise/prefer-await-to-then */ 'use client'; import { type CustomerInput } from '@repo/graphql/types'; import { Input } from '@repo/ui/components/ui/input'; import { Label } from '@repo/ui/components/ui/label'; import { type ChangeEvent, useEffect, useRef, useState } from 'react'; import { useDebouncedCallback } from 'use-debounce'; type ProfileFieldProps = { readonly disabled?: boolean; readonly fieldName?: keyof CustomerInput; readonly id: string; readonly label: string; readonly onChange?: (value: CustomerInput) => Promise | void; readonly readOnly?: boolean; readonly value: string; }; export function DataField({ disabled = false, fieldName, id, label, onChange, readOnly, value: initialValue, }: ProfileFieldProps) { const [value, setValue] = useState(initialValue); const { debouncedCallback, isPending } = useDebouncedOnChangeCallback(onChange, fieldName); const inputRef = useFocus(isPending); const handleChange = (event: ChangeEvent) => { const newValue = event.target.value; setValue(newValue); debouncedCallback(newValue); }; return (
); } function useDebouncedOnChangeCallback( callback: ((value: CustomerInput) => Promise | void) | undefined, fieldName: string | undefined, ) { const [isPending, setIsPending] = useState(false); const debouncedCallback = useDebouncedCallback((newValue: string) => { if (!callback || !fieldName) return; setIsPending(true); const result = callback({ [fieldName]: newValue }); if (result instanceof Promise) { result.finally(() => setIsPending(false)); } else { setIsPending(false); } }, 300); return { debouncedCallback, isPending, }; } function useFocus(isPending: boolean) { const inputRef = useRef(null); const [isInitialRender, setIsInitialRender] = useState(true); useEffect(() => { if (isInitialRender) { setIsInitialRender(false); return; } if (inputRef.current && isPending) { inputRef.current.focus(); } }, [isInitialRender, isPending]); return inputRef; }