import React, { useCallback, useState } from 'react'; import { useDropzone } from 'react-dropzone'; import { motion, AnimatePresence } from 'framer-motion'; import { CloudArrowUpIcon, DocumentIcon, CheckCircleIcon, XCircleIcon, XMarkIcon } from '@heroicons/react/24/outline'; import { uploadDocument } from '../services/api'; import toast from 'react-hot-toast'; const FileUploader = ({ darkMode, onClose }) => { const [uploading, setUploading] = useState(false); const [uploadedFiles, setUploadedFiles] = useState([]); const onDrop = useCallback(async (acceptedFiles) => { setUploading(true); for (const file of acceptedFiles) { try { console.log(`Starting upload for file: ${file.name}, size: ${file.size} bytes`); const formData = new FormData(); formData.append('file', file); // Check file size limits const maxSize = 100 * 1024 * 1024; // 100MB if (file.size > maxSize) { toast.error(`${file.name} is too large (${formatFileSize(file.size)}). Maximum size is 100MB.`); setUploadedFiles(prev => [...prev, { name: file.name, size: file.size, status: 'error', error: 'File too large (max 100MB)' }]); continue; // Skip this file } else if (file.size > 10 * 1024 * 1024) { toast(`Warning: ${file.name} is large (${formatFileSize(file.size)}). Upload may take time.`, { icon: '⚠️', duration: 6000 }); } await uploadDocument(formData); setUploadedFiles(prev => [...prev, { name: file.name, size: file.size, status: 'success' }]); toast.success(`${file.name} uploaded successfully!`); console.log(`Successfully uploaded: ${file.name}`); } catch (error) { console.error(`Failed to upload ${file.name}:`, error); setUploadedFiles(prev => [...prev, { name: file.name, size: file.size, status: 'error', error: error.message }]); // More specific error messages let errorMessage = `Failed to upload ${file.name}`; if (error.message.includes('Network Error')) { errorMessage += ': Network connection failed. Check if the server is running.'; } else if (error.message.includes('timeout')) { errorMessage += ': Upload timed out. File may be too large.'; } else if (error.message.includes('413')) { errorMessage += ': File too large (max 100MB allowed).'; } else if (error.message.includes('415')) { errorMessage += ': Unsupported file type.'; } else if (error.message.includes('500')) { errorMessage += ': Server error. Check server logs.'; } else { errorMessage += `: ${error.message}`; } toast.error(errorMessage); } } setUploading(false); }, []); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: { 'application/pdf': ['.pdf'], 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'], 'text/plain': ['.txt'] }, multiple: true }); const formatFileSize = (bytes) => { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; const removeFile = (index) => { setUploadedFiles(prev => prev.filter((_, i) => i !== index)); }; return (
{/* Dropzone */}

{isDragActive ? 'Drop files here' : 'Upload study materials'}

Drag & drop files here, or click to browse

Maximum file size: 100MB

PDF DOCX TXT
{/* Upload Progress */} {uploading && (
Uploading files...
)} {/* Uploaded Files List */} {uploadedFiles.length > 0 && (

Uploaded Files

{uploadedFiles.map((file, index) => (

{file.name}

{formatFileSize(file.size)}

{file.status === 'success' ? ( ) : ( )}
))}
)}
{/* Close Button */} {onClose && (
)}
); }; export default FileUploader;