Add invoice drafts, read-only issued state and keyboard shortcuts

Views stay mounted so switching tabs no longer loses a half-typed invoice.
The form autosaves a draft after 1 s, drafts can be resumed or deleted,
and after issuing the form is read-only with Export again, Duplicate and
New invoice actions. A failed export keeps the issued invoice and offers a
retry instead of issuing again. Adds Ctrl+N/S/Enter/L and a shortcut sheet;
F5 and Ctrl+R are blocked in production builds.
This commit is contained in:
2026-10-04 04:21:47 +05:30
parent 5597fb791d
commit fbed18a0bd
8 changed files with 859 additions and 62 deletions
+4 -3
View File
@@ -20,7 +20,7 @@ import { formatAmount, formatDate } from "../lib/format";
import { exportInvoicePdf } from "../lib/pdf";
import type { InvoiceSummary, Settings } from "../lib/types";
export default function InvoiceHistory({ settings }: { settings: Settings }) {
export default function InvoiceHistory({ settings, active }: { settings: Settings; active: boolean }) {
const [rows, setRows] = useState<InvoiceSummary[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@@ -39,9 +39,10 @@ export default function InvoiceHistory({ settings }: { settings: Settings }) {
}
};
// The view stays mounted, so refetch every time it is shown again.
useEffect(() => {
void load();
}, []);
if (active) void load();
}, [active]);
const onExport = async (id: number) => {
setBusyId(id);