From 623d378faff6dd81fded1df902a07d5db9093363 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Nov 2025 19:55:42 +0000 Subject: [PATCH] Architect navigation buttons correctly: move from wizard-level to step-level Fixed the navigation architecture to follow proper onboarding patterns: **ARCHITECTURE CHANGE:** - REMOVED: External navigation footer from UnifiedOnboardingWizard (Back + Continue buttons at wizard level) - ADDED: Internal Continue buttons inside each setup wizard step component **WHY THIS MATTERS:** 1. Onboarding should NEVER show Back buttons (users cannot go back) 2. Each step should be self-contained with its own Continue button 3. Setup wizard steps are reused in both contexts: - SetupWizard (/app/setup): Uses external StepNavigation component - UnifiedOnboardingWizard: Steps now render their own buttons **CHANGES MADE:** 1. UnifiedOnboardingWizard.tsx: - Removed navigation footer (lines 548-588) - Now passes canContinue prop to steps - Steps are responsible for their own navigation 2. All setup wizard steps updated: - QualitySetupStep: Added onComplete, canContinue props + Continue button - SuppliersSetupStep: Modified existing button to call onComplete - InventorySetupStep: Added onComplete, canContinue props + Continue button - RecipesSetupStep: Added canContinue prop + Continue button - TeamSetupStep: Added onComplete, canContinue props + Continue button - ReviewSetupStep: Added onComplete, canContinue props + Continue button 3. Continue button pattern: - Only renders when onComplete prop exists (onboarding context) - Disabled based on canContinue prop from parent - Styled consistently across all steps - Positioned at bottom with border-top separator **RESULT:** - Clean separation: onboarding steps have internal buttons, no external navigation - No Back button in onboarding (as required) - Setup wizard still works with external StepNavigation - Consistent UX across all steps --- .../onboarding/UnifiedOnboardingWizard.tsx | 43 +------------------ .../setup-wizard/steps/InventorySetupStep.tsx | 15 ++++++- .../setup-wizard/steps/QualitySetupStep.tsx | 15 ++++++- .../setup-wizard/steps/RecipesSetupStep.tsx | 15 ++++++- .../setup-wizard/steps/ReviewSetupStep.tsx | 15 ++++++- .../setup-wizard/steps/SuppliersSetupStep.tsx | 6 +-- .../setup-wizard/steps/TeamSetupStep.tsx | 15 ++++++- 7 files changed, 74 insertions(+), 50 deletions(-) diff --git a/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx b/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx index eb898e41..ed4af6c0 100644 --- a/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx +++ b/frontend/src/components/domain/onboarding/UnifiedOnboardingWizard.tsx @@ -542,50 +542,9 @@ const OnboardingWizardContent: React.FC = () => { onUpdate={handleStepUpdate} isFirstStep={currentStepIndex === 0} isLastStep={currentStepIndex === VISIBLE_STEPS.length - 1} + canContinue={canContinue} /> - - {/* Navigation Footer - Only for setup wizard steps that don't render their own buttons */} - {['suppliers-setup', 'inventory-setup', 'recipes-setup', 'quality-setup', 'team-setup', 'setup-review'].includes(currentStep.id) && ( -
-
- {/* Left side - Back button */} -
- {currentStepIndex > 0 && ( - - )} -
- - {/* Right side - Continue button */} -
- -
-
-
- )} ); diff --git a/frontend/src/components/domain/setup-wizard/steps/InventorySetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/InventorySetupStep.tsx index def9e5b6..d2d788d8 100644 --- a/frontend/src/components/domain/setup-wizard/steps/InventorySetupStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/InventorySetupStep.tsx @@ -8,7 +8,7 @@ import { UnitOfMeasure, IngredientCategory } from '../../../../api/types/invento import type { IngredientCreate, IngredientUpdate } from '../../../../api/types/inventory'; import { ESSENTIAL_INGREDIENTS, COMMON_INGREDIENTS, PACKAGING_ITEMS, type IngredientTemplate, templateToIngredientCreate } from '../data/ingredientTemplates'; -export const InventorySetupStep: React.FC = ({ onUpdate }) => { +export const InventorySetupStep: React.FC = ({ onUpdate, onComplete, canContinue }) => { const { t } = useTranslation(); // Get tenant ID @@ -669,6 +669,19 @@ export const InventorySetupStep: React.FC = ({ onUpdate }) => {

)} + + {/* Continue button - only shown when used in onboarding context */} + {onComplete && ( +
+ +
+ )} ); }; diff --git a/frontend/src/components/domain/setup-wizard/steps/QualitySetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/QualitySetupStep.tsx index 04fc56d9..293ab343 100644 --- a/frontend/src/components/domain/setup-wizard/steps/QualitySetupStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/QualitySetupStep.tsx @@ -7,7 +7,7 @@ import { useAuthUser } from '../../../../stores/auth.store'; import { QualityCheckType, ProcessStage } from '../../../../api/types/qualityTemplates'; import type { QualityCheckTemplateCreate } from '../../../../api/types/qualityTemplates'; -export const QualitySetupStep: React.FC = ({ onUpdate }) => { +export const QualitySetupStep: React.FC = ({ onUpdate, onComplete, canContinue }) => { const { t } = useTranslation(); // Get tenant ID and user @@ -416,6 +416,19 @@ export const QualitySetupStep: React.FC = ({ onUpdate }) => {

)} + + {/* Continue button - only shown when used in onboarding context */} + {onComplete && ( +
+ +
+ )} ); }; diff --git a/frontend/src/components/domain/setup-wizard/steps/RecipesSetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/RecipesSetupStep.tsx index c0a5c1ab..74f99621 100644 --- a/frontend/src/components/domain/setup-wizard/steps/RecipesSetupStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/RecipesSetupStep.tsx @@ -17,7 +17,7 @@ interface RecipeIngredientForm { ingredient_order: number; } -export const RecipesSetupStep: React.FC = ({ onUpdate, onComplete }) => { +export const RecipesSetupStep: React.FC = ({ onUpdate, onComplete, canContinue }) => { const { t } = useTranslation(); // Get tenant ID @@ -793,6 +793,19 @@ export const RecipesSetupStep: React.FC = ({ onUpdate, onComplet tenantId={tenantId} context="recipe" /> + + {/* Continue button - only shown when used in onboarding context */} + {onComplete && ( +
+ +
+ )} ); }; diff --git a/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx index 2ea3fa6f..55672265 100644 --- a/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx @@ -8,7 +8,7 @@ import { useQualityTemplates } from '../../../../api/hooks/qualityTemplates'; import { useCurrentTenant } from '../../../../stores/tenant.store'; import { useAuthUser } from '../../../../stores/auth.store'; -export const ReviewSetupStep: React.FC = ({ onUpdate }) => { +export const ReviewSetupStep: React.FC = ({ onUpdate, onComplete, canContinue }) => { const { t } = useTranslation(); // Get tenant ID @@ -306,6 +306,19 @@ export const ReviewSetupStep: React.FC = ({ onUpdate }) => { )} + + {/* Continue button - only shown when used in onboarding context */} + {onComplete && ( +
+ +
+ )} ); }; diff --git a/frontend/src/components/domain/setup-wizard/steps/SuppliersSetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/SuppliersSetupStep.tsx index 98ea13a4..c9c18f33 100644 --- a/frontend/src/components/domain/setup-wizard/steps/SuppliersSetupStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/SuppliersSetupStep.tsx @@ -14,6 +14,7 @@ export const SuppliersSetupStep: React.FC = ({ onComplete, onSkip, onUpdate, + canContinue, isFirstStep, isLastStep }) => { @@ -471,12 +472,11 @@ export const SuppliersSetupStep: React.FC = ({ )} diff --git a/frontend/src/components/domain/setup-wizard/steps/TeamSetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/TeamSetupStep.tsx index 50208d3a..b61431c3 100644 --- a/frontend/src/components/domain/setup-wizard/steps/TeamSetupStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/TeamSetupStep.tsx @@ -9,7 +9,7 @@ interface TeamMember { role: string; } -export const TeamSetupStep: React.FC = ({ onUpdate }) => { +export const TeamSetupStep: React.FC = ({ onUpdate, onComplete, canContinue }) => { const { t } = useTranslation(); // Local state for team members (will be sent to backend when API is available) @@ -310,6 +310,19 @@ export const TeamSetupStep: React.FC = ({ onUpdate }) => {

)} + + {/* Continue button - only shown when used in onboarding context */} + {onComplete && ( +
+ +
+ )} ); };