render setup wizard steps by key

This commit is contained in:
Josh Hawkins
2026-08-26 11:50:44 -05:00
parent f25d785380
commit c7a0c426ca
+30 -16
View File
@@ -9,17 +9,25 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import { useTheme } from "@/context/theme-provider"; import { useTheme } from "@/context/theme-provider";
import { dismissSetup } from "@/utils/setupWizard"; import { dismissSetup } from "@/utils/setupWizard";
import { useCallback, useReducer } from "react"; import { useCallback, useMemo, useReducer } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { LuMoon, LuSun } from "react-icons/lu"; import { LuMoon, LuSun } from "react-icons/lu";
const STEPS = [ type StepKey =
"setupWizard.steps.welcome", | "welcome"
"setupWizard.steps.camera", | "camera"
"setupWizard.steps.detector", | "detector"
"setupWizard.steps.hwaccel", | "hwaccel"
"setupWizard.steps.recording", | "recording"
"setupWizard.steps.complete", | "complete";
const STEP_KEYS: StepKey[] = [
"welcome",
"camera",
"detector",
"hwaccel",
"recording",
"complete",
]; ];
type WizardState = { type WizardState = {
@@ -114,6 +122,12 @@ export default function SetupWizard() {
const [state, dispatch] = useReducer(wizardReducer, initialState); const [state, dispatch] = useReducer(wizardReducer, initialState);
const { theme, systemTheme, setTheme } = useTheme(); const { theme, systemTheme, setTheme } = useTheme();
const steps = STEP_KEYS;
const stepLabels = useMemo(
() => steps.map((key) => `setupWizard.steps.${key}`),
[steps],
);
const isDark = (theme === "system" ? systemTheme : theme) === "dark"; const isDark = (theme === "system" ? systemTheme : theme) === "dark";
const handleSkipSetup = useCallback(() => { const handleSkipSetup = useCallback(() => {
@@ -161,17 +175,17 @@ export default function SetupWizard() {
}, []); }, []);
const renderStep = () => { const renderStep = () => {
switch (state.currentStep) { switch (steps[state.currentStep]) {
case 0: case "welcome":
return ( return (
<SetupWelcome <SetupWelcome
onNext={() => dispatch({ type: "NEXT_STEP" })} onNext={() => dispatch({ type: "NEXT_STEP" })}
onSkip={handleSkipSetup} onSkip={handleSkipSetup}
/> />
); );
case 1: case "camera":
return <SetupCamera onNext={handleCameraNext} onBack={handleBack} />; return <SetupCamera onNext={handleCameraNext} onBack={handleBack} />;
case 2: case "detector":
return ( return (
<SetupDetector <SetupDetector
cameraCount={state.cameraNames.length} cameraCount={state.cameraNames.length}
@@ -180,7 +194,7 @@ export default function SetupWizard() {
onSkip={handleDetectorSkip} onSkip={handleDetectorSkip}
/> />
); );
case 3: case "hwaccel":
return ( return (
<SetupHwAccel <SetupHwAccel
detectorHardwareKey={state.detectorHardwareKey} detectorHardwareKey={state.detectorHardwareKey}
@@ -190,7 +204,7 @@ export default function SetupWizard() {
onSkip={handleSkipStep} onSkip={handleSkipStep}
/> />
); );
case 4: case "recording":
return ( return (
<SetupRecording <SetupRecording
cameraNames={state.cameraNames} cameraNames={state.cameraNames}
@@ -199,7 +213,7 @@ export default function SetupWizard() {
onSkip={handleSkipStep} onSkip={handleSkipStep}
/> />
); );
case 5: case "complete":
return ( return (
<SetupComplete <SetupComplete
cameraNames={state.cameraNames} cameraNames={state.cameraNames}
@@ -231,7 +245,7 @@ export default function SetupWizard() {
<Card className="w-full max-w-lg"> <Card className="w-full max-w-lg">
<CardContent className="p-6"> <CardContent className="p-6">
<StepIndicator <StepIndicator
steps={STEPS} steps={stepLabels}
currentStep={state.currentStep} currentStep={state.currentStep}
variant="dots" variant="dots"
translationNameSpace="views/setup" translationNameSpace="views/setup"