import { useState, useRef } from 'react'; import { UploadCloud, AlertCircle, CheckCircle, X } from 'lucide-react'; import { processSourceText } from '../../lib/extractionPipeline'; import Card from '../ui/Card'; import Button from '../ui/Button'; // ── Main Component ──────────────────────────────────────────────────────────── const UploadZone = ({ onUploadComplete }) => { const [isDragging, setIsDragging] = useState(false); const [isProcessing, setIsProcessing] = useState(false); const [status, setStatus] = useState(null); const fileInputRef = useRef(null); const abortRef = useRef(null); // ── File upload (drag & drop / browse) ──────────────────────────────────── const processFile = async (file) => { setIsProcessing(true); setStatus(null); const controller = new AbortController(); abortRef.current = controller; try { const text = await file.text(); await processSourceText(text, file.name, { signal: controller.signal }); setStatus({ type: 'success', msg: `Successfully processed: ${file.name}` }); if (onUploadComplete) onUploadComplete(); } catch (error) { if (error?.name === 'AbortError') { setStatus({ type: 'error', msg: `Cancelled: ${file.name}` }); } else { setStatus({ type: 'error', msg: `Error processing file: ${error.message}` }); } } finally { abortRef.current = null; setIsProcessing(false); } }; const cancelProcessing = () => { abortRef.current?.abort(new DOMException('Cancelled by user', 'AbortError')); }; const handleDragOver = (e) => { e.preventDefault(); setIsDragging(true); }; const handleDragLeave = () => setIsDragging(false); const handleDrop = (e) => { e.preventDefault(); setIsDragging(false); if (e.dataTransfer.files?.length > 0) { const file = e.dataTransfer.files[0]; if (file.type === 'text/plain' || file.name.endsWith('.md')) { processFile(file); } else { setStatus({ type: 'error', msg: 'Only .txt and .md files are currently supported.' }); } } }; const handleFileSelect = (e) => { if (e.target.files?.length > 0) processFile(e.target.files[0]); }; // ── Render ───────────────────────────────────────────────────────────────── return (
Drag files here
Supports .txt and .md (max 5MB)
{status.type === 'error' ? 'Error' : 'Success'}
{status.msg}