function Spinner({ config }) { const ref = React.useRef(null); React.useEffect(() => { const spinner = new Spin.Spinner({ lines: 13, color: "#ffffff", ...config, }); spinner.spin(ref.current); return () => spinner.stop(); }, [ref]); return ; } function Result({ callId, selectedFile }) { const [result, setResult] = React.useState(); const [intervalId, setIntervalId] = React.useState(); React.useEffect(() => { if (result) { clearInterval(intervalId); return; } const _intervalID = setInterval(async () => { const resp = await fetch(`/result/${callId}`); if (resp.status === 200) { setResult(await resp.json()); } }, 100); setIntervalId(_intervalID); return () => clearInterval(intervalId); }, [result]); return (
{!result && } {result && (

{JSON.stringify(result, undefined, 1)}

)}
); } function Form({ onSubmit, onFileSelect, selectedFile }) { return (
Receipt Parser
{selectedFile ? ( ) : null}
); } function App() { const [selectedFile, setSelectedFile] = React.useState(); const [callId, setCallId] = React.useState(); const handleSubmission = async () => { const formData = new FormData(); formData.append("receipt", selectedFile); const resp = await fetch("/parse", { method: "POST", body: formData, }); if (resp.status !== 200) { throw new Error("An error occurred: " + resp.status); } const body = await resp.json(); setCallId(body.call_id); }; return (
{!callId && (
setSelectedFile(e.target.files[0])} selectedFile={selectedFile} /> )} {callId && }
); } const container = document.getElementById("react"); ReactDOM.createRoot(container).render();