Add toasts, Settings tabs, Clients page and item presets (Phase E1)
- Global Carbon toast stack replaces scattered inline notices; errors persist until closed. - Settings is split into eight tabs with one Save and a remembered last tab; Numbering embeds the series settings. - New Clients page with a DataTable, shared add/edit modal, structured addresses, GST category (informational), per-client notes and payment terms. The composed address string is kept for back-compat. Deleting a client warns about invoice count; issued invoices keep their own snapshot. - Migration M7 adds the client columns and item_presets; existing clients with a GSTIN are backfilled to registered_regular. - New invoice form: client ComboBox with type-ahead and inline create, client defaults applied on selection, and an Add from preset control. - Rust tests for M7 (fresh and v6 upgrade), client validation and CRUD, presets CRUD; vitest for the toast store and new helpers. PDF output and fingerprint goldens are unchanged. The new UI has not been run in a webview yet.
This commit is contained in:
+14
-4
@@ -6,10 +6,20 @@ import { AppShell, type AppView } from "./components/AppShell";
|
||||
import Onboarding from "./views/Onboarding";
|
||||
import NewInvoice from "./views/NewInvoice";
|
||||
import InvoiceHistory from "./views/InvoiceHistory";
|
||||
import SeriesSettings from "./views/SeriesSettings";
|
||||
import Clients from "./views/Clients";
|
||||
import { ToastProvider, useToast } from "./components/ToastProvider";
|
||||
import AppSettings from "./views/AppSettings";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<ToastProvider>
|
||||
<AppInner />
|
||||
</ToastProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function AppInner() {
|
||||
const toast = useToast();
|
||||
const [settings, setSettings] = useState<Settings | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
@@ -81,7 +91,7 @@ export default function App() {
|
||||
try {
|
||||
await api.saveSettings(next);
|
||||
} catch (e) {
|
||||
setError(String(e));
|
||||
toast.error("Could not save the theme", String(e));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -98,8 +108,8 @@ export default function App() {
|
||||
<div hidden={view !== "invoices"}>
|
||||
<InvoiceHistory settings={settings} active={view === "invoices"} />
|
||||
</div>
|
||||
<div hidden={view !== "series"}>
|
||||
<SeriesSettings active={view === "series"} />
|
||||
<div hidden={view !== "clients"}>
|
||||
<Clients active={view === "clients"} />
|
||||
</div>
|
||||
{view === "settings" && <AppSettings settings={settings} onSaved={refreshSettings} />}
|
||||
</AppShell>
|
||||
|
||||
Reference in New Issue
Block a user