Start the setup wizard blank and add a Run setup again button
The first-run seed no longer inserts the original vendor's name, address, contact details, PAN or bank account; the wizard now starts empty and requires a name and state. Settings > Data gets a Run setup again button that clears the onboarded flag. Re-running the wizard keeps the active invoice series unless the prefix or padding changes. The sample logo moves out of public/ so it no longer ships in the app.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Button, InlineLoading, InlineNotification, Modal, Tile, Toggle } from "@carbon/react";
|
||||
import { open, save } from "@tauri-apps/plugin-dialog";
|
||||
import { confirm, open, save } from "@tauri-apps/plugin-dialog";
|
||||
import { api } from "../lib/api";
|
||||
import type { Settings } from "../lib/types";
|
||||
import {
|
||||
backupFileName,
|
||||
ensureZipExtension,
|
||||
@@ -20,8 +21,15 @@ type RestoreStep = "confirm" | "staging" | "ready";
|
||||
const joinPath = (dir: string, name: string) =>
|
||||
!dir ? name : /[\\/]$/.test(dir) ? `${dir}${name}` : `${dir}${dir.includes("\\") && !dir.includes("/") ? "\\" : "/"}${name}`;
|
||||
|
||||
/** Settings > Data: manual backup, restore (staged, applied after a restart) and the automatic daily backup. */
|
||||
export default function DataBackupPanel() {
|
||||
interface DataBackupPanelProps {
|
||||
/** The saved settings; "Run setup again" writes them back with the wizard flag cleared. */
|
||||
settings: Settings;
|
||||
/** Called after the flag is cleared, so the app reloads settings and shows the wizard. */
|
||||
onRerunSetup: () => void;
|
||||
}
|
||||
|
||||
/** Settings > Data: manual backup, restore (staged, applied after a restart), the automatic daily backup and re-running setup. */
|
||||
export default function DataBackupPanel({ settings, onRerunSetup }: DataBackupPanelProps) {
|
||||
const toast = useToast();
|
||||
const [status, setStatus] = useState<BackupStatus | null>(null);
|
||||
const [backingUp, setBackingUp] = useState(false);
|
||||
@@ -32,6 +40,20 @@ export default function DataBackupPanel() {
|
||||
const [restarting, setRestarting] = useState(false);
|
||||
useReturnFocus(restorePath !== null);
|
||||
|
||||
const rerunSetup = async () => {
|
||||
const ok = await confirm(
|
||||
"Open the setup wizard again? Your invoices, clients and backups are kept, and the wizard starts with your current details.",
|
||||
{ title: "Run setup again", kind: "warning" },
|
||||
);
|
||||
if (!ok) return;
|
||||
try {
|
||||
await api.saveSettings({ ...settings, onboarded: false });
|
||||
onRerunSetup();
|
||||
} catch (e) {
|
||||
toast.error("Could not start setup", String(e));
|
||||
}
|
||||
};
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
try {
|
||||
setStatus(await api.getBackupStatus());
|
||||
@@ -229,6 +251,19 @@ export default function DataBackupPanel() {
|
||||
</div>
|
||||
</Tile>
|
||||
|
||||
<Tile>
|
||||
<h2 className="voiced-section-title">Setup wizard</h2>
|
||||
<p className="voiced-muted">
|
||||
Run the first-time setup again to change your business details, logo, bank account and numbering in one go. Existing
|
||||
invoices, clients and backups are not touched, and invoice numbering carries on unless you change the prefix.
|
||||
</p>
|
||||
<div className="voiced-actions">
|
||||
<Button size="md" kind="tertiary" onClick={() => void rerunSetup()}>
|
||||
Run setup again
|
||||
</Button>
|
||||
</div>
|
||||
</Tile>
|
||||
|
||||
<Modal
|
||||
open={restorePath !== null}
|
||||
danger={step === "confirm"}
|
||||
|
||||
Reference in New Issue
Block a user