diff --git a/frontend/src/components/domain/setup-wizard/SetupWizard.tsx b/frontend/src/components/domain/setup-wizard/SetupWizard.tsx index 090748ae..435de719 100644 --- a/frontend/src/components/domain/setup-wizard/SetupWizard.tsx +++ b/frontend/src/components/domain/setup-wizard/SetupWizard.tsx @@ -13,6 +13,7 @@ import { RecipesSetupStep, QualitySetupStep, TeamSetupStep, + ReviewSetupStep, CompletionStep } from './steps'; @@ -24,6 +25,7 @@ const STEP_WEIGHTS = { 'recipes-setup': 20, // 10 min (heavy) 'quality-setup': 15, // 7 min (moderate) 'team-setup': 10, // 5 min (optional) + 'setup-review': 5, // 2 min (light, informational) 'setup-completion': 5 // 2 min (light) }; @@ -114,6 +116,15 @@ export const SetupWizard: React.FC = () => { estimatedMinutes: 5, weight: STEP_WEIGHTS['team-setup'] }, + { + id: 'setup-review', + title: t('setup_wizard:steps.review.title', 'Review Your Setup'), + description: t('setup_wizard:steps.review.description', 'Confirm your configuration'), + component: ReviewSetupStep, + isOptional: false, + estimatedMinutes: 2, + weight: STEP_WEIGHTS['setup-review'] + }, { id: 'setup-completion', title: t('setup_wizard:steps.completion.title', 'You\'re All Set!'), diff --git a/frontend/src/components/domain/setup-wizard/steps/CompletionStep.tsx b/frontend/src/components/domain/setup-wizard/steps/CompletionStep.tsx index 8a1279ac..f539c8df 100644 --- a/frontend/src/components/domain/setup-wizard/steps/CompletionStep.tsx +++ b/frontend/src/components/domain/setup-wizard/steps/CompletionStep.tsx @@ -1,131 +1,242 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../../ui/Button'; import type { SetupStepProps } from '../SetupWizard'; -export const CompletionStep: React.FC = ({ onComplete }) => { +export const CompletionStep: React.FC = ({ onComplete, onUpdate }) => { const { t } = useTranslation(); const navigate = useNavigate(); + // Always allow to continue (but there's no next step) + useEffect(() => { + onUpdate?.({ + itemsCount: 1, + canContinue: true, + }); + }, [onUpdate]); + + const nextSteps = [ + { + icon: ( + + + + ), + title: t('setup_wizard:completion.step1_title', 'Start Production'), + description: t('setup_wizard:completion.step1_desc', 'Create your first production batch using your configured recipes'), + action: t('setup_wizard:completion.step1_action', 'Go to Production'), + link: '/app/operations/production', + }, + { + icon: ( + + + + ), + title: t('setup_wizard:completion.step2_title', 'Order Inventory'), + description: t('setup_wizard:completion.step2_desc', 'Place your first purchase order with your suppliers'), + action: t('setup_wizard:completion.step2_action', 'View Procurement'), + link: '/app/operations/procurement', + }, + { + icon: ( + + + + ), + title: t('setup_wizard:completion.step3_title', 'Track Analytics'), + description: t('setup_wizard:completion.step3_desc', 'Monitor your production efficiency and costs in real-time'), + action: t('setup_wizard:completion.step3_action', 'View Analytics'), + link: '/app/analytics/production', + }, + ]; + + const tips = [ + { + icon: '💡', + title: t('setup_wizard:completion.tip1_title', 'Keep Inventory Updated'), + description: t('setup_wizard:completion.tip1_desc', 'Regularly update stock levels to get accurate cost calculations and low-stock alerts'), + }, + { + icon: '📊', + title: t('setup_wizard:completion.tip2_title', 'Monitor Quality Metrics'), + description: t('setup_wizard:completion.tip2_desc', 'Use quality checks during production to identify issues early and maintain consistency'), + }, + { + icon: '🎯', + title: t('setup_wizard:completion.tip3_title', 'Review Analytics Weekly'), + description: t('setup_wizard:completion.tip3_desc', 'Check your production analytics every week to optimize recipes and reduce waste'), + }, + { + icon: '🤝', + title: t('setup_wizard:completion.tip4_title', 'Maintain Supplier Relationships'), + description: t('setup_wizard:completion.tip4_desc', 'Keep supplier information current and track order performance for better partnerships'), + }, + ]; + const handleGoToDashboard = () => { - onComplete({ completed: true }); + onComplete?.({ completed: true }); navigate('/app/dashboard'); }; return ( -
- {/* Success Icon */} -
- - - -
- - {/* Success Message */} -
-

- {t('setup_wizard:completion.title', 'You\'re All Set! 🎉')} +
+ {/* Celebration Header */} +
+
+ + + +
+

+ {t('setup_wizard:completion.title', '🎉 Setup Complete!')}

- {t('setup_wizard:completion.subtitle', 'Your bakery management system is fully configured and ready to help you run your operations more efficiently.')} + {t('setup_wizard:completion.subtitle', "Congratulations! Your bakery management system is ready to use. Let's get started with your first tasks.")}

- {/* Setup Summary */} -
-

- {t('setup_wizard:completion.summary_title', 'Setup Summary')} -

-
-
- - - - {t('setup_wizard:completion.summary_suppliers', 'Suppliers configured')} -
-
- - - - {t('setup_wizard:completion.summary_inventory', 'Inventory items added')} -
-
- - - - {t('setup_wizard:completion.summary_recipes', 'Recipes created')} -
-
- - - - {t('setup_wizard:completion.summary_quality', 'Quality standards defined')} -
+ {/* Confetti Effect Placeholder */} +
+
+
🎊🎉🎊
- {/* What You Can Do Now */} -
-

- {t('setup_wizard:completion.what_now_title', 'What You Can Do Now')} -

-
-
-
- 📦 + {/* Next Steps */} +
+

+ + + + {t('setup_wizard:completion.next_steps', 'Recommended Next Steps')} +

+
+ {nextSteps.map((step, index) => ( +
navigate(step.link)} + > +
+
+ {step.icon} +
+
+

+ {step.title} +

+

+ {step.description} +

+
+
+
-

- {t('setup_wizard:completion.feature_inventory', 'Track Inventory')} -

-

- {t('setup_wizard:completion.feature_inventory_desc', 'Real-time stock levels & alerts')} -

-
- -
-
- 👨‍🍳 -
-

- {t('setup_wizard:completion.feature_production', 'Create Production Orders')} -

-

- {t('setup_wizard:completion.feature_production_desc', 'Plan daily baking with your recipes')} -

-
- -
-
- 💰 -
-

- {t('setup_wizard:completion.feature_costs', 'Analyze Costs')} -

-

- {t('setup_wizard:completion.feature_costs_desc', 'See exact costs per recipe')} -

-
- -
-
- 📈 -
-

- {t('setup_wizard:completion.feature_forecasts', 'View AI Forecasts')} -

-

- {t('setup_wizard:completion.feature_forecasts_desc', 'Demand predictions for your products')} -

-
+ ))}
- {/* Action Button */} -
- + {/* Pro Tips */} +
+

+ + + + {t('setup_wizard:completion.tips', 'Pro Tips for Success')} +

+
+ {tips.map((tip, index) => ( +
+
+
{tip.icon}
+
+

+ {tip.title} +

+

+ {tip.description} +

+
+
+
+ ))} +
+
+ + {/* Quick Links */} +
+

+ + + + {t('setup_wizard:completion.need_help', 'Need Help?')} +

+
+ + + + + +
+
+ + {/* Final CTA */} +
+ +

+ {t('setup_wizard:completion.thanks', 'Thank you for completing the setup! Happy baking! 🥖🥐🍰')} +

); diff --git a/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx b/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx new file mode 100644 index 00000000..2ea3fa6f --- /dev/null +++ b/frontend/src/components/domain/setup-wizard/steps/ReviewSetupStep.tsx @@ -0,0 +1,311 @@ +import React, { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import type { SetupStepProps } from '../SetupWizard'; +import { useSuppliers } from '../../../../api/hooks/suppliers'; +import { useIngredients } from '../../../../api/hooks/inventory'; +import { useRecipes } from '../../../../api/hooks/recipes'; +import { useQualityTemplates } from '../../../../api/hooks/qualityTemplates'; +import { useCurrentTenant } from '../../../../stores/tenant.store'; +import { useAuthUser } from '../../../../stores/auth.store'; + +export const ReviewSetupStep: React.FC = ({ onUpdate }) => { + const { t } = useTranslation(); + + // Get tenant ID + const currentTenant = useCurrentTenant(); + const user = useAuthUser(); + const tenantId = currentTenant?.id || user?.tenant_id || ''; + + // Fetch all data for review + const { data: suppliersData, isLoading: suppliersLoading } = useSuppliers(tenantId); + const { data: ingredientsData, isLoading: ingredientsLoading } = useIngredients(tenantId); + const { data: recipesData, isLoading: recipesLoading } = useRecipes(tenantId); + const { data: qualityTemplatesData, isLoading: qualityLoading } = useQualityTemplates(tenantId); + + const suppliers = suppliersData || []; + const ingredients = ingredientsData || []; + const recipes = recipesData || []; + const qualityTemplates = qualityTemplatesData || []; + + const isLoading = suppliersLoading || ingredientsLoading || recipesLoading || qualityLoading; + + // Always allow to continue (review step is informational) + useEffect(() => { + onUpdate?.({ + itemsCount: suppliers.length + ingredients.length + recipes.length, + canContinue: true, + }); + }, [suppliers.length, ingredients.length, recipes.length, onUpdate]); + + // Calculate some helpful stats + const totalCost = ingredients.reduce((sum, ing) => sum + (ing.standard_cost || 0), 0); + const avgRecipeIngredients = recipes.length > 0 + ? recipes.reduce((sum, recipe) => sum + (recipe.ingredients?.length || 0), 0) / recipes.length + : 0; + + return ( +
+ {/* Header */} +
+
+ + + +
+

+ {t('setup_wizard:review.title', 'Review Your Setup')} +

+

+ {t('setup_wizard:review.subtitle', "Let's review everything you've configured. You can go back and make changes if needed.")} +

+
+ + {isLoading ? ( +
+ + + + +

+ {t('common:loading', 'Loading...')} +

+
+ ) : ( + <> + {/* Overview Stats */} +
+
+
+
+

{t('setup_wizard:review.suppliers', 'Suppliers')}

+

{suppliers.length}

+
+ + + +
+
+ +
+
+
+

{t('setup_wizard:review.ingredients', 'Ingredients')}

+

{ingredients.length}

+
+ + + +
+
+ +
+
+
+

{t('setup_wizard:review.recipes', 'Recipes')}

+

{recipes.length}

+
+ + + +
+
+ +
+
+
+

{t('setup_wizard:review.quality', 'Quality Checks')}

+

{qualityTemplates.length}

+
+ + + +
+
+
+ + {/* Detailed Sections */} +
+ {/* Suppliers Section */} + {suppliers.length > 0 && ( +
+
+

+ + + + {t('setup_wizard:review.suppliers_title', 'Suppliers')} + ({suppliers.length}) +

+
+
+ {suppliers.slice(0, 6).map((supplier) => ( +
+
+

{supplier.name}

+ {supplier.email && ( +

{supplier.email}

+ )} +
+ {supplier.is_active && ( + + )} +
+ ))} + {suppliers.length > 6 && ( +
+ +{suppliers.length - 6} {t('setup_wizard:review.more', 'more')} +
+ )} +
+
+ )} + + {/* Ingredients Section */} + {ingredients.length > 0 && ( +
+
+

+ + + + {t('setup_wizard:review.ingredients_title', 'Inventory Items')} + ({ingredients.length}) +

+ {totalCost > 0 && ( +

+ {t('setup_wizard:review.total_cost', 'Total value')}: ${totalCost.toFixed(2)} +

+ )} +
+
+ {ingredients.slice(0, 8).map((ingredient) => ( +
+
+

{ingredient.name}

+

{ingredient.unit_of_measure}

+
+
+ ))} + {ingredients.length > 8 && ( +
+ +{ingredients.length - 8} {t('setup_wizard:review.more', 'more')} +
+ )} +
+
+ )} + + {/* Recipes Section */} + {recipes.length > 0 && ( +
+
+

+ + + + {t('setup_wizard:review.recipes_title', 'Recipes')} + ({recipes.length}) +

+ {avgRecipeIngredients > 0 && ( +

+ {t('setup_wizard:review.avg_ingredients', 'Avg ingredients')}: {avgRecipeIngredients.toFixed(1)} +

+ )} +
+
+ {recipes.slice(0, 4).map((recipe) => ( +
+
+

{recipe.name}

+
+ + {recipe.ingredients?.length || 0} {t('setup_wizard:review.ingredients', 'ingredients')} + + + {t('setup_wizard:review.yields', 'Yields')}: {recipe.yield_quantity} {recipe.yield_unit} + + {recipe.category && ( + + {recipe.category} + + )} +
+
+ {recipe.estimated_cost_per_unit && ( +
+

{t('setup_wizard:review.cost', 'Cost')}

+

${Number(recipe.estimated_cost_per_unit).toFixed(2)}

+
+ )} +
+ ))} + {recipes.length > 4 && ( +
+ +{recipes.length - 4} {t('setup_wizard:review.more', 'more')} +
+ )} +
+
+ )} + + {/* Quality Templates Section */} + {qualityTemplates.length > 0 && ( +
+
+

+ + + + {t('setup_wizard:review.quality_title', 'Quality Check Templates')} + ({qualityTemplates.length}) +

+
+
+ {qualityTemplates.map((template) => ( +
+
+

{template.name}

+

{template.check_type}

+
+ {template.is_required && ( + + {t('setup_wizard:review.required', 'Required')} + + )} +
+ ))} +
+
+ )} +
+ + {/* Summary Message */} +
+ + + +

+ {t('setup_wizard:review.ready_title', 'Your Bakery is Ready to Go!')} +

+

+ {t('setup_wizard:review.ready_message', + "You've successfully configured {suppliers} suppliers, {ingredients} ingredients, and {recipes} recipes. Click 'Complete Setup' to finish and start using the system.", + { suppliers: suppliers.length, ingredients: ingredients.length, recipes: recipes.length } + )} +

+
+ + {/* Help Text */} +
+

+ + + + {t('setup_wizard:review.help', 'Need to make changes? Use the "Back" button to return to any step.')} +

+
+ + )} +
+ ); +}; diff --git a/frontend/src/components/domain/setup-wizard/steps/index.ts b/frontend/src/components/domain/setup-wizard/steps/index.ts index c2a69c2c..5d655d8a 100644 --- a/frontend/src/components/domain/setup-wizard/steps/index.ts +++ b/frontend/src/components/domain/setup-wizard/steps/index.ts @@ -4,4 +4,5 @@ export { InventorySetupStep } from './InventorySetupStep'; export { RecipesSetupStep } from './RecipesSetupStep'; export { QualitySetupStep } from './QualitySetupStep'; export { TeamSetupStep } from './TeamSetupStep'; +export { ReviewSetupStep } from './ReviewSetupStep'; export { CompletionStep } from './CompletionStep';