import { useState } from "react"; import Modal from "../ui/Modal"; import Button from "../ui/Button"; import Field, { inputClass } from "../ui/Field"; import { exportSettings } from "../../lib/tauri-commands"; interface Props { onClose: () => void; } const MIN_PASSWORD_LENGTH = 8; /** * Password entry for exporting global settings. The save dialog itself opens * from Rust once a password is confirmed here — see the doc comment on * `commands::settings_export_commands` for why the host path never * round-trips through this component. */ export default function ExportSettingsModal({ onClose }: Props) { const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [done, setDone] = useState(false); const mismatch = confirmPassword.length > 0 && password !== confirmPassword; const tooShort = password.length > 0 && password.length < MIN_PASSWORD_LENGTH; const canSubmit = password.length >= MIN_PASSWORD_LENGTH && password === confirmPassword; const handleExport = async () => { setError(null); setBusy(true); try { const saved = await exportSettings(password); if (saved) setDone(true); // `false` means the save dialog was dismissed — close quietly, same as // if the user had cancelled the modal itself. else onClose(); } catch (e) { setError(String(e)); } finally { setBusy(false); } }; return ( Done ) : ( <> ) } > {done ? (

Settings exported. Keep the password somewhere safe — there is no way to recover the file without it.

) : (
{(id) => ( setPassword(e.target.value)} disabled={busy} className={inputClass} /> )} {(id) => ( setConfirmPassword(e.target.value)} disabled={busy} className={inputClass} /> )} {tooShort && (

Use at least {MIN_PASSWORD_LENGTH} characters.

)} {mismatch &&

Passwords don't match.

} {error &&

{error}

}
)}
); }