import { useCallback, useState } from "react"; import { Upload, FileAudio, FileVideo, X, AlertCircle } from "lucide-react"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Label } from "@/components/ui/label"; import { Progress } from "@/components/ui/progress"; import { Badge } from "@/components/ui/badge"; interface FileUploadProps { onUpload: (file: File, context: string) => void; isUploading: boolean; uploadProgress: number; } const MAX_FILE_SIZE = 25 * 1024 * 1024; // 25MB const ACCEPTED_TYPES = ["audio/mpeg", "audio/mp3", "video/mp4"]; export function FileUpload({ onUpload, isUploading, uploadProgress }: FileUploadProps) { const [file, setFile] = useState(null); const [context, setContext] = useState(""); const [dragOver, setDragOver] = useState(false); const [error, setError] = useState(null); const wordCount = context.trim().split(/\s+/).filter(Boolean).length; const isContextValid = wordCount <= 100; const validateFile = useCallback((file: File): string | null => { if (file.size > MAX_FILE_SIZE) { return `File is too large. Maximum size is 25MB. Your file is ${(file.size / 1024 / 1024).toFixed(1)}MB.`; } const isValidType = ACCEPTED_TYPES.includes(file.type) || file.name.endsWith('.mp3') || file.name.endsWith('.mp4'); if (!isValidType) { return "Invalid file type. Please upload an MP3 or MP4 file."; } return null; }, []); const handleFileSelect = useCallback((selectedFile: File) => { const validationError = validateFile(selectedFile); if (validationError) { setError(validationError); setFile(null); return; } setError(null); setFile(selectedFile); }, [validateFile]); const handleDrop = useCallback((e: React.DragEvent) => { e.preventDefault(); setDragOver(false); const droppedFile = e.dataTransfer.files[0]; if (droppedFile) { handleFileSelect(droppedFile); } }, [handleFileSelect]); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); setDragOver(true); }, []); const handleDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault(); setDragOver(false); }, []); const handleInputChange = useCallback((e: React.ChangeEvent) => { const selectedFile = e.target.files?.[0]; if (selectedFile) { handleFileSelect(selectedFile); } }, [handleFileSelect]); const handleSubmit = () => { if (file && isContextValid) { onUpload(file, context); } }; const clearFile = () => { setFile(null); setError(null); }; const getFileIcon = () => { if (!file) return null; if (file.type.startsWith("video") || file.name.endsWith(".mp4")) { return ; } return ; }; return (
{file ? (
{getFileIcon()}

{file.name}

{(file.size / 1024 / 1024).toFixed(2)} MB

{isUploading && (

Uploading... {uploadProgress}%

)}
) : (

Drop your audio or video file here

or click to browse

MP3 MP4 up to 25MB
)}
{error && (

{error}

)}
{wordCount}/100 words