import FileUpload from "@moduletrace/twui/form/FileUpload"; import Button from "@moduletrace/twui/layout/Button"; import Tag from "@moduletrace/twui/elements/Tag"; import Row from "@moduletrace/twui/layout/Row"; import Stack from "@moduletrace/twui/layout/Stack"; import useStatus from "@moduletrace/twui/hooks/useStatus"; import { useState } from "react"; import { Upload } from "lucide-react"; type Props = { /** * The file picker's hint, e.g. "Click or drop a SQLite database file". */ label: string; /** * What the picker accepts, e.g. `.db,.sqlite,.sqlite3`. */ accept?: string; /** * The button's label. */ action_label: string; /** * Sends the file and reports the outcome. */ upload: (params: { file: File }) => Promise<{ success: boolean; msg?: string }>; /** * Reload the page once it worked (the app restarts after an archive * restore, so the caller waits for it first). */ onDone: () => void; }; /** * Picks one file and sends it for a restore: shared by the database upload * and the data archive upload, which differ only in what they accept. */ export default function UploadRestoreFields({ label, accept, action_label, upload, onDone, }: Props) { const { loading, setLoading, status, setStatus } = useStatus(); const [file, setFile] = useState(); const send = async () => { if (!file) return; setStatus(undefined); setLoading(true); const res = await upload({ file }); if (res.success) { onDone(); return; } setLoading(false); if (res.msg) { setStatus({ error: true, msg: res.msg }); } }; return ( { setStatus(undefined); setFile(file_data?.file); }} /> {status?.error && {status.msg}} ); }