fix(onboarding): derive step counter from STEP_ORDER
All six step panels previously hard-coded "X / 5" or "X / 6" in their header captions, which drifted out of sync with the 7-step STEP_ORDER in OnboardingHero. Export STEP_ORDER / TOTAL_STEPS / getStepNumber from OnboardingHero and consume them in every step so the counter is always the single source of truth.
This commit is contained in:
1 parent
5a5587c2a1
commit
183f22e922
7 files changed
+23
-9
No files matched your search
@@ -3,6 +3,7 @@ import { Buildings, FolderOpen } from "@phosphor-icons/react";
|
||||
import type { ConnectorId, ProfileSnapshot } from "@shared/types";
|
||||
import type { AppLocale } from "@shared/locale";
|
||||
import { ActionButton, Input, TextArea, Select } from "../ui";
|
||||
import { getStepNumber, TOTAL_STEPS } from "./OnboardingHero";
|
||||
|
||||
interface CompanyStepProps {
|
||||
companyName: string;
|
||||
@@ -57,7 +58,7 @@ export function CompanyStep({
|
||||
className="bg-card border border-border shadow-sm w-full rounded-lg p-7"
|
||||
>
|
||||
<div className="mb-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||
{t("onboarding.stepLabelCompany")} 3 / 6
|
||||
{t("onboarding.stepLabelCompany")} {getStepNumber("company")} / {TOTAL_STEPS}
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-foreground">
|
||||
{t("onboarding.step1Title")}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowRight, Brain, UserCircle, type Icon } from "@phosphor-icons/react";
|
||||
import type { ExecutionMode } from "@shared/types";
|
||||
import { getStepNumber, TOTAL_STEPS } from "./OnboardingHero";
|
||||
|
||||
interface ExecutionModeStepProps {
|
||||
executionMode: ExecutionMode;
|
||||
@@ -27,7 +28,7 @@ export function ExecutionModeStep({
|
||||
className="bg-card border border-border shadow-sm w-full rounded-lg p-7"
|
||||
>
|
||||
<div className="mb-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||
{t("onboarding.stepLabelMode")} 5 / 6
|
||||
{t("onboarding.stepLabelMode")} {getStepNumber("executionmode")} / {TOTAL_STEPS}
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-foreground">
|
||||
{t("onboarding.modeStepTitle")}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { motion } from "framer-motion";
|
||||
import { Cpu, Lightning } from "@phosphor-icons/react";
|
||||
import { ActionButton, Input, TextArea } from "../ui";
|
||||
import { getStepNumber, TOTAL_STEPS } from "./OnboardingHero";
|
||||
|
||||
interface MissionStepProps {
|
||||
goalTitle: string;
|
||||
@@ -35,7 +36,7 @@ export function MissionStep({
|
||||
className="bg-card border border-border shadow-sm w-full rounded-lg p-7"
|
||||
>
|
||||
<div className="mb-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||
{t("onboarding.stepLabelMission")} 6 / 6
|
||||
{t("onboarding.stepLabelMission")} {getStepNumber("mission")} / {TOTAL_STEPS}
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-foreground">
|
||||
{t("onboarding.step2Title")}
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ConnectorId, ProfileSnapshot } from "@shared/types";
|
||||
import type { AppLocale } from "@shared/locale";
|
||||
import { ActionButton } from "../ui";
|
||||
import { ModelToggleList, StatusBadge } from "../execution/ModelManagementShared";
|
||||
import { getStepNumber, TOTAL_STEPS } from "./OnboardingHero";
|
||||
|
||||
interface ModelPoolStepProps {
|
||||
currentLocale: AppLocale;
|
||||
@@ -52,7 +53,7 @@ export function ModelPoolStep({
|
||||
className="w-full rounded-lg border border-border bg-card p-7 shadow-sm"
|
||||
>
|
||||
<div className="mb-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||
{t("onboarding.stepLabelModelPool")} 4 / 6
|
||||
{t("onboarding.stepLabelModelPool")} {getStepNumber("modelpool")} / {TOTAL_STEPS}
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-foreground">
|
||||
{t("onboarding.modelPoolStepTitle")}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from "@phosphor-icons/react";
|
||||
import { ActionButton } from "../ui";
|
||||
import type { TerminalCommandKey } from "@shared/contracts";
|
||||
import { getStepNumber, TOTAL_STEPS } from "./OnboardingHero";
|
||||
|
||||
interface NodeCheckStepProps {
|
||||
nodeStatus: { installed: boolean; version: string | null } | null;
|
||||
@@ -69,7 +70,7 @@ export function NodeCheckStep({
|
||||
className="bg-card border border-border shadow-sm w-full rounded-lg p-7"
|
||||
>
|
||||
<div className="mb-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||
{t("onboarding.stepLabel1")} 1 / 5 — {t("onboarding.nodeCheckStep")}
|
||||
{t("onboarding.stepLabel1")} {getStepNumber("nodecheck")} / {TOTAL_STEPS} — {t("onboarding.nodeCheckStep")}
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-foreground">
|
||||
{t("onboarding.nodeCheckTitle")}
|
||||
|
||||
@@ -31,7 +31,7 @@ const STEP_LABELS_CONFIG = [
|
||||
{ key: "onboarding.stepLabelLaunch", icon: Rocket, step: "launch" as const },
|
||||
] as const;
|
||||
|
||||
const STEP_ORDER: OnboardingStep[] = [
|
||||
export const STEP_ORDER = [
|
||||
"nodecheck",
|
||||
"providers",
|
||||
"company",
|
||||
@@ -39,7 +39,15 @@ const STEP_ORDER: OnboardingStep[] = [
|
||||
"executionmode",
|
||||
"mission",
|
||||
"launch",
|
||||
];
|
||||
] as const satisfies readonly OnboardingStep[];
|
||||
|
||||
export type OnboardingStepName = (typeof STEP_ORDER)[number];
|
||||
|
||||
export const TOTAL_STEPS = STEP_ORDER.length;
|
||||
|
||||
export function getStepNumber(step: OnboardingStepName): number {
|
||||
return STEP_ORDER.indexOf(step) + 1;
|
||||
}
|
||||
|
||||
interface OnboardingHeroProps {
|
||||
step: OnboardingStep;
|
||||
@@ -52,7 +60,7 @@ export function OnboardingHero({
|
||||
currentLocale: _currentLocale,
|
||||
t,
|
||||
}: OnboardingHeroProps) {
|
||||
const stepIndex = STEP_ORDER.indexOf(step);
|
||||
const stepIndex = (STEP_ORDER as readonly OnboardingStep[]).indexOf(step);
|
||||
|
||||
const stepLabels = STEP_LABELS_CONFIG.map((cfg) => ({
|
||||
label: t(cfg.key),
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
StatusBadge,
|
||||
INPUT_CLS,
|
||||
} from "./ProvidersStepShared";
|
||||
import { getStepNumber, TOTAL_STEPS } from "./OnboardingHero";
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Props */
|
||||
@@ -104,7 +105,7 @@ export function ProvidersStep({
|
||||
className="w-full rounded-lg border border-border bg-card p-7 shadow-sm"
|
||||
>
|
||||
<div className="mb-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">
|
||||
{t("onboarding.stepLabelProviders")} 2 / 6
|
||||
{t("onboarding.stepLabelProviders")} {getStepNumber("providers")} / {TOTAL_STEPS}
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-foreground">
|
||||
{t("onboarding.providersTitle")}
|
||||
|
||||
Reference in new issue
Block a user