import React, { memo, useState, useEffect, useCallback, useRef } from 'react'; interface DebouncedInputProps { value: string; onChange: (value: string) => void; placeholder?: string; className?: string; type?: 'text' | 'textarea'; rows?: number; } // Memoized input component that manages its own state export const DebouncedInput = memo(({ value, onChange, placeholder, className, type = 'text', rows = 5 }: DebouncedInputProps) => { const [localValue, setLocalValue] = useState(value); const timeoutRef = useRef(); const isFirstRender = useRef(true); // Sync with external value only on mount or when externally changed useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } // Only update if the external value is different from local if (value !== localValue) { setLocalValue(value); } }, [value]); const handleChange = useCallback((e: React.ChangeEvent) => { const newValue = e.target.value; setLocalValue(newValue); // Clear existing timeout if (timeoutRef.current) { clearTimeout(timeoutRef.current); } // Set new timeout for debounced update timeoutRef.current = setTimeout(() => { onChange(newValue); }, 300); }, [onChange]); // Cleanup timeout on unmount useEffect(() => { return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, []); if (type === 'textarea') { return (