'use client' import * as React from 'react' import type { UploadProgress } from '@admin/types' import { Button } from '@admin/components/ui/button' import { Card, CardContent } from '@admin/components/ui/card' import { Progress } from '@admin/components/ui/progress' import { cn } from '@admin/utils/shared/cn' import { parseDropzoneAccept } from '@admin/utils/upload/parse-dropzone-accept' import { GalleryVerticalEnd } from 'lucide-react' import { useDropzone } from 'react-dropzone' export interface UploadDropzoneHandle { openFileDialog: () => void } export interface UploadDropzoneProps { onFilesSelected: (files: File[]) => void progress: UploadProgress[] isUploading: boolean accept?: string multiple?: boolean className?: string disabled?: boolean ref?: React.Ref } export function UploadDropzone({ onFilesSelected, progress, isUploading, accept, multiple = true, className, disabled = false, ref }: UploadDropzoneProps) { const progressPercent = React.useMemo(() => { if (progress.length === 0) return 0 return Math.round(progress.reduce((sum, item) => sum + item.progress, 0) / progress.length) }, [progress]) const handleDrop = React.useCallback( (files: File[]) => { if (files.length === 0) return onFilesSelected(files) }, [onFilesSelected] ) const parsedAccept = React.useMemo(() => parseDropzoneAccept(accept), [accept]) const { getRootProps, getInputProps, isDragActive, open } = useDropzone({ noClick: true, noKeyboard: true, multiple, accept: parsedAccept, disabled: isUploading || disabled, onDrop: handleDrop }) React.useImperativeHandle(ref, () => ({ openFileDialog: open }), [open]) return ( {isUploading ? (

Uploading files…

{progressPercent}% complete

) : (

Drag & drop images, videos, or documents here

)}
) }