import React, { useState, useCallback } from 'react'; import { UploadCloud, File, Sheet, Loader2, CheckCircle, Sparkles, Wand2, BarChart3 } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { generateSyntheticCsv } from '../utils/syntheticDataGenerator'; import { TierKey } from '../types'; interface DataUploaderProps { selectedTier: TierKey; onAnalysisReady: () => void; isAnalyzing: boolean; } type UploadStatus = 'idle' | 'generating' | 'uploading' | 'success'; const formatFileSize = (bytes: number, decimals = 2) => { if (bytes === 0) return '0 Bytes'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; }; const DataUploader: React.FC = ({ selectedTier, onAnalysisReady, isAnalyzing }) => { const { t } = useTranslation(); const [file, setFile] = useState(null); const [sheetUrl, setSheetUrl] = useState(''); const [status, setStatus] = useState('idle'); const [successMessage, setSuccessMessage] = useState(''); const [error, setError] = useState(''); const [isDragging, setIsDragging] = useState(false); const isActionInProgress = status === 'generating' || status === 'uploading' || isAnalyzing; const resetState = (clearAll: boolean = true) => { setStatus('idle'); setError(''); setSuccessMessage(''); if (clearAll) { setFile(null); setSheetUrl(''); } }; const handleDataReady = (message: string) => { setStatus('success'); setSuccessMessage(message); }; const handleFileChange = (selectedFile: File | null) => { resetState(); if (selectedFile) { const allowedTypes = [ 'text/csv', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ]; if (allowedTypes.includes(selectedFile.type) || selectedFile.name.endsWith('.csv') || selectedFile.name.endsWith('.xlsx') || selectedFile.name.endsWith('.xls')) { setFile(selectedFile); setSheetUrl(''); } else { setError(t('upload.invalidFileType')); setFile(null); } } }; const onDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); if (!isActionInProgress) setIsDragging(true); }, [isActionInProgress]); const onDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setIsDragging(false); }, []); const onDrop = useCallback((e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setIsDragging(false); if (isActionInProgress) return; const droppedFile = e.dataTransfer.files && e.dataTransfer.files[0]; handleFileChange(droppedFile); }, [isActionInProgress]); const handleGenerateSyntheticData = () => { resetState(); setStatus('generating'); setTimeout(() => { const csvData = generateSyntheticCsv(selectedTier); handleDataReady(t('upload.syntheticDataGenerated')); }, 2000); }; const handleSubmit = () => { if (!file && !sheetUrl) { setError(t('upload.pleaseUploadFile')); return; } resetState(false); setStatus('uploading'); setTimeout(() => { handleDataReady(t('upload.dataReceived')); }, 2000); }; const renderMainButton = () => { if (status === 'success') { return ( ); } return ( ); }; return (
{t('stepper.step2')}

{t('upload.title')}

{t('upload.subtitle')}

handleFileChange(e.target.files ? e.target.files[0] : null)} disabled={isActionInProgress} />

{t('common.or')}

{t('upload.noDataPrompt')}


{t('common.or')}
{ resetState(); setSheetUrl(e.target.value); setFile(null); }} disabled={isActionInProgress} className="w-full pl-10 pr-4 py-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition disabled:bg-slate-100" />
{error &&

{error}

} {status !== 'uploading' && status !== 'success' && file && (
{file.name} {formatFileSize(file.size)}
)} {status === 'uploading' && file && (
{file.name} {formatFileSize(file.size)}
)} {status !== 'uploading' && status !== 'success' && sheetUrl && !file && (
{sheetUrl}
)} {status === 'success' && (
{successMessage} {t('upload.readyToAnalyze')}
)} {renderMainButton()}
); }; export default DataUploader;