import React, { useState, useRef } from 'react'; import { X, Upload, CheckCircle, AlertCircle } from 'lucide-react'; const UploadZone = () => { const [isDragging, setIsDragging] = useState(false); const [files, setFiles] = useState([]); const fileInputRef = useRef(null); const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 Mo const ALLOWED_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'wmv', 'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf', 'rar', 'm3u', 'm3u8', 'txt']; const handleDragOver = (e) => { e.preventDefault(); setIsDragging(true); }; const handleDragLeave = (e) => { e.preventDefault(); setIsDragging(false); }; const validateFile = (file) => { const extension = file.name.split('.').pop().toLowerCase(); if (!ALLOWED_EXTENSIONS.includes(extension)) { return { valid: false, error: `Extension .${extension} non autorisée` }; } if (file.size > MAX_FILE_SIZE) { return { valid: false, error: 'Fichier trop volumineux (max 100 Mo)' }; } return { valid: true, error: null }; }; const handleDrop = (e) => { e.preventDefault(); setIsDragging(false); const droppedFiles = Array.from(e.dataTransfer.files); addFiles(droppedFiles); }; const handleFileSelect = (e) => { const selectedFiles = Array.from(e.target.files); addFiles(selectedFiles); }; const addFiles = (newFiles) => { const processedFiles = newFiles.map(file => { const validation = validateFile(file); return { file, id: Math.random().toString(36).substring(7), status: validation.valid ? 'pending' : 'error', error: validation.error, progress: 0 }; }); setFiles(currentFiles => [...currentFiles, ...processedFiles]); }; const removeFile = (fileId) => { setFiles(files => files.filter(f => f.id !== fileId)); }; const uploadFile = async (fileInfo) => { const formData = new FormData(); formData.append('file', fileInfo.file); formData.append('action', 'upload'); try { // Simuler un upload progressif pour la démo await new Promise(resolve => { let progress = 0; const interval = setInterval(() => { progress += 10; setFiles(files => files.map(f => f.id === fileInfo.id ? { ...f, progress, status: progress === 100 ? 'complete' : 'uploading' } : f ) ); if (progress >= 100) { clearInterval(interval); resolve(); } }, 500); }); } catch (error) { setFiles(files => files.map(f => f.id === fileInfo.id ? { ...f, status: 'error', error: 'Erreur lors du téléversement' } : f ) ); } }; const uploadAllFiles = () => { const pendingFiles = files.filter(f => f.status === 'pending'); pendingFiles.forEach(uploadFile); }; const getStatusColor = (status) => { switch (status) { case 'complete': return 'text-green-500'; case 'error': return 'text-red-500'; case 'uploading': return 'text-blue-500'; default: return 'text-gray-500'; } }; const getStatusIcon = (status) => { switch (status) { case 'complete': return ; case 'error': return ; default: return null; } }; return (
fileInputRef.current?.click()} > `.${ext}`).join(',')} />

Glissez-déposez vos fichiers ici

ou cliquez pour sélectionner des fichiers

Max 100 Mo par fichier · {ALLOWED_EXTENSIONS.join(', ')}

{files.length > 0 && (

Files ({files.length})

{files.map((fileInfo) => (

{fileInfo.file.name}

{(fileInfo.file.size / 1024 / 1024).toFixed(2)} Mo

{fileInfo.error && (

{fileInfo.error}

)}
{fileInfo.status === 'uploading' && (
)}
{getStatusIcon(fileInfo.status)}
))}
)}
); }; export default UploadZone;