import { useCallback, useRef, useState } from "react"; import { uploadFile, uploadText } from "./api"; const MAX_MB = 10; // UI state machine: idle → uploading → (ready | error), with error/ready // returning to idle on a new attempt. const IDLE = "idle"; const UPLOADING = "uploading"; const READY = "ready"; const ERROR = "error"; export default function DocumentUploader({ onReady }) { const [state, setState] = useState(IDLE); const [error, setError] = useState(null); const [doc, setDoc] = useState(null); const [dragging, setDragging] = useState(false); const [mode, setMode] = useState("file"); // "file" | "text" const [text, setText] = useState(""); const inputRef = useRef(null); const submit = useCallback( async (promise) => { setState(UPLOADING); setError(null); try { const payload = await promise; setDoc(payload); setState(READY); onReady?.(payload); } catch (err) { setError(err.message); setState(ERROR); } }, [onReady], ); const handleFile = useCallback( (file) => { if (!file) return; const isPdf = file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf"); if (!isPdf) { setError("Only PDF files are supported."); setState(ERROR); return; } if (file.size > MAX_MB * 1024 * 1024) { setError(`File is too large (max ${MAX_MB} MB).`); setState(ERROR); return; } submit(uploadFile(file)); }, [submit], ); const onDrop = useCallback( (e) => { e.preventDefault(); setDragging(false); handleFile(e.dataTransfer.files?.[0]); }, [handleFile], ); const reset = () => { setState(IDLE); setError(null); setDoc(null); setText(""); }; if (state === READY && doc) { return (
{doc.filename || "Pasted text"}
id: {doc.document_id}
Parsing…
> ) : ( <> 📄Drag a PDF here, or click to browse
PDF up to {MAX_MB} MB
> )}