"use client"; import { useCallback } from "react"; import { useDropzone } from "react-dropzone"; import { motion, AnimatePresence } from "framer-motion"; import { Upload, File, X, FileVideo, FileImage, Music } from "lucide-react"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { formatFileSize, getFileExtension } from "@/lib/utils"; import type { UploadedFile } from "@/types"; interface FileUploaderProps { onFilesDrop: (files: File[]) => void; files: UploadedFile[]; onRemoveFile: (id: string) => void; accept?: Record; maxSize?: number; maxFiles?: number; disabled?: boolean; } const defaultAccept = { "image/*": [".png", ".jpg", ".jpeg", ".webp"], "video/*": [".mp4", ".mov", ".avi", ".webm"], "audio/*": [".mp3", ".wav", ".ogg", ".aac"], }; export function FileUploader({ onFilesDrop, files, onRemoveFile, accept = defaultAccept, maxSize = 50 * 1024 * 1024, // 50MB maxFiles = 10, disabled = false, }: FileUploaderProps) { const onDrop = useCallback( (acceptedFiles: File[]) => { if (disabled) return; onFilesDrop(acceptedFiles); }, [onFilesDrop, disabled] ); const { getRootProps, getInputProps, isDragActive, isDragReject } = useDropzone({ onDrop, accept, maxSize, maxFiles, disabled, multiple: maxFiles > 1, }); const getFileIcon = (file: File) => { if (file.type.startsWith("image/")) return FileImage; if (file.type.startsWith("video/")) return FileVideo; if (file.type.startsWith("audio/")) return Music; return File; }; return (
{/* Dropzone */}

{isDragActive ? "Drop your files here" : isDragReject ? "File type not accepted" : "Drag & drop files here"}

or click to browse • Max {formatFileSize(maxSize)} • Up to {maxFiles} file {maxFiles > 1 ? "s" : ""}

{/* File List */} {files.length > 0 && ( {files.map((file, index) => { const Icon = getFileIcon(file.file); return (

{file.name}

{formatFileSize(file.size)} • {getFileExtension(file.name).toUpperCase()}

{file.file.type.split("/")[1].toUpperCase()}
); })}
)}
); }