feat(01-04): add onboarding wizard with settings API and persisted state
- Settings API: GET/PUT /api/settings/:key with SQLite persistence - useSettings hook with TanStack Query for settings CRUD - OnboardingWizard: 3-step modal overlay (welcome, create category, add item) - Root layout checks onboarding completion flag before rendering wizard - Skip option available at every step, all paths persist completion to DB Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { useState } from "react";
|
||||
import { createRootRoute, Outlet } from "@tanstack/react-router";
|
||||
import "../app.css";
|
||||
import { TotalsBar } from "../components/TotalsBar";
|
||||
import { SlideOutPanel } from "../components/SlideOutPanel";
|
||||
import { ItemForm } from "../components/ItemForm";
|
||||
import { ConfirmDialog } from "../components/ConfirmDialog";
|
||||
import { OnboardingWizard } from "../components/OnboardingWizard";
|
||||
import { useUIStore } from "../stores/uiStore";
|
||||
import { useOnboardingComplete } from "../hooks/useSettings";
|
||||
|
||||
export const Route = createRootRoute({
|
||||
component: RootLayout,
|
||||
@@ -16,8 +19,24 @@ function RootLayout() {
|
||||
const openAddPanel = useUIStore((s) => s.openAddPanel);
|
||||
const closePanel = useUIStore((s) => s.closePanel);
|
||||
|
||||
const { data: onboardingComplete, isLoading: onboardingLoading } =
|
||||
useOnboardingComplete();
|
||||
const [wizardDismissed, setWizardDismissed] = useState(false);
|
||||
|
||||
const showWizard =
|
||||
!onboardingLoading && onboardingComplete !== "true" && !wizardDismissed;
|
||||
|
||||
const isOpen = panelMode !== "closed";
|
||||
|
||||
// Show a minimal loading state while checking onboarding status
|
||||
if (onboardingLoading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="w-6 h-6 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<TotalsBar />
|
||||
@@ -59,6 +78,11 @@ function RootLayout() {
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Onboarding Wizard */}
|
||||
{showWizard && (
|
||||
<OnboardingWizard onComplete={() => setWizardDismissed(true)} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user