import { useState } from 'react'; import { Loader2, Upload } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useTranslation } from '@/contexts/language'; interface PhotoDropzoneProps { /** Called with the image files the user picked or dropped. */ onFiles: (files: File[]) => void | Promise; /** Show a spinner and block input while an upload is in flight. */ uploading?: boolean; /** Disable interaction (e.g. while the form is submitting). */ disabled?: boolean; /** Allow more than one file at a time. Defaults to true. */ multiple?: boolean; /** Primary tile label. */ label?: string; /** Secondary line under the label (hidden while dragging). */ hint?: string; /** Wrapper classes — pass sizing such as `aspect-video` here. */ className?: string; /** Accessible name for the file input. Defaults to `label`. */ inputLabel?: string; } const IMAGE_RE = /^image\//; /** * A drop target for images that also works as click-to-browse. * * Users can select or drop several photos at once, instead of adding them one * at a time. Collecting the files is all this does — uploading is the caller's * responsibility via `onFiles`, so each screen keeps its own toasts/progress. */ export function PhotoDropzone({ onFiles, uploading = false, disabled = false, multiple = true, label, hint, className, inputLabel, }: PhotoDropzoneProps) { const { t } = useTranslation(); const [dragging, setDragging] = useState(false); const busy = uploading || disabled; const resolvedLabel = label ?? t('spotUi.addPhotos'); const resolvedHint = hint ?? t('spotUi.dragDropOrClick'); const emit = (fileList: FileList | null) => { if (!fileList) return; const files = Array.from(fileList).filter((f) => IMAGE_RE.test(f.type)); if (files.length > 0) void onFiles(files); }; return ( ); }