- Add ThemeToggle segmented control (Light/Dark/System) with DOM class toggle - Use getStored() lazy init and applyTheme() for side-effect-free render - Stub localStorage and matchMedia in tests for Node v25 compatibility - Wire ThemeToggle into App.tsx header flex row next to h1 - Change App outer div to bg-surface, h1 to text-on-surface - All 7 ThemeToggle unit tests passing; 166 total tests green
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
// src/App.tsx
|
|
// Step router — renders the correct step component based on currentStep.
|
|
// StepIndicator renders above each step as persistent breadcrumb navigation.
|
|
|
|
import { useWizard } from './store/context';
|
|
import { WizardProvider } from './store/context';
|
|
import { ThemeToggle } from './components/ui/ThemeToggle';
|
|
import { StepIndicator } from './components/wizard/StepIndicator';
|
|
import { BackendSelectionStep } from './components/wizard/BackendSelectionStep';
|
|
import { RemoteConfigStep } from './components/wizard/RemoteConfigStep';
|
|
import { DeploymentStep } from './components/wizard/DeploymentStep';
|
|
import { ReviewStep } from './components/wizard/ReviewStep';
|
|
|
|
function WizardShell() {
|
|
const { state } = useWizard();
|
|
|
|
const steps = [
|
|
<BackendSelectionStep key="backend" />,
|
|
// Key on backendType to force remount when backend changes — prevents stale form values
|
|
<RemoteConfigStep key={state.remote.backendType ?? 'none'} />,
|
|
<DeploymentStep key="deployment" />,
|
|
<ReviewStep key="review" />,
|
|
];
|
|
|
|
// Guard: clamp to valid range
|
|
const stepIndex = Math.min(state.currentStep, steps.length - 1);
|
|
const CurrentStep = steps[stepIndex];
|
|
|
|
return (
|
|
<div className="min-h-screen bg-surface flex flex-col items-center py-12 px-4">
|
|
<div className="w-full max-w-2xl">
|
|
<div className="flex items-center justify-between mb-8">
|
|
<h1 className="text-3xl font-bold text-on-surface">Ready2Blob</h1>
|
|
<ThemeToggle />
|
|
</div>
|
|
<StepIndicator />
|
|
<div className="mt-8">
|
|
{CurrentStep}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<WizardProvider>
|
|
<WizardShell />
|
|
</WizardProvider>
|
|
);
|
|
}
|