import React, { useCallback, useState } from 'react'; import { UploadCloud, FileUp } from 'lucide-react'; import { FileItem, UploadStatus } from '../types'; const generateId = () => Math.random().toString(36).substring(2, 15); interface FileUploaderProps { onFilesAdded: (files: FileItem[]) => void; disabled: boolean; } const sanitizeFileName = (fileName: string): string => { const timestamp = Date.now(); const lastDotIndex = fileName.lastIndexOf('.'); const name = lastDotIndex !== -1 ? fileName.substring(0, lastDotIndex) : fileName; const ext = lastDotIndex !== -1 ? fileName.substring(lastDotIndex) : ''; let cleanName = name; cleanName = cleanName.replace(/^\d+[-_.\s]*/, ''); cleanName = cleanName.normalize("NFD").replace(/[\u0300-\u036f]/g, "") .replace(/đ/g, 'd').replace(/Đ/g, 'D'); cleanName = cleanName.replace(/[^a-zA-Z0-9]/g, '-'); cleanName = cleanName.replace(/-+/g, '-').replace(/^-|-$/g, ''); if (cleanName.length === 0) cleanName = 'file'; return `${timestamp}-${cleanName}${ext}`.toLowerCase(); }; export const FileUploader: React.FC = ({ onFilesAdded, disabled }) => { const [isDragging, setIsDragging] = useState(false); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); if (!disabled) setIsDragging(true); }, [disabled]); const handleDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); }, []); const handleDrop = useCallback((e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); if (disabled) return; if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { processFiles(e.dataTransfer.files); } }, [disabled]); const handleFileInput = (e: React.ChangeEvent) => { if (e.target.files && e.target.files.length > 0) { processFiles(e.target.files); e.target.value = ''; // Reset input } }; const processFiles = (fileList: FileList) => { const newFiles: FileItem[] = Array.from(fileList).map(file => { const cleanPath = sanitizeFileName(file.name); return { id: generateId(), file, path: cleanPath, status: UploadStatus.IDLE }; }); onFilesAdded(newFiles); }; return (
{/* Decorative Background Glow */}

{isDragging ? 'Drop files instantly' : 'Click or Drag files here'}

Supports images, JSON, CSV, and Parquet. Files are auto-renamed with timestamps

Bulk Upload Supported
); };