import { cn } from '@/lib/utils'; import { UploadCloud } from 'lucide-react'; import { useCallback, useState } from 'react'; import { Spinner } from './spinner'; type FileDropZoneProps = { accept?: string; isLoading?: boolean; label?: string; hint?: string; onFile: (file: File) => void; className?: string; id?: string; }; const FileDropZone = ({ accept, isLoading = false, label = 'Drop file here', hint = 'or click to browse', onFile, className, id = 'file-drop-zone-input', }: FileDropZoneProps) => { const [isDragging, setIsDragging] = useState(false); const onDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); const file = e.dataTransfer.files[0]; if (file) onFile(file); }, [onFile], ); const onFileChange = useCallback( (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) onFile(file); e.target.value = ''; }, [onFile], ); return (
{ e.preventDefault(); setIsDragging(true); }} onDragLeave={() => setIsDragging(false)} onDrop={onDrop} onClick={() => document.getElementById(id)?.click()} className={cn( 'flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed px-6 py-8 transition-colors', isDragging ? 'border-teal-400 bg-teal-50' : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50', className, )} > {isLoading ? ( ) : ( <>

{label}

{hint}

)}
); }; export { FileDropZone };