2025-08-28 10:41:04 +02:00
|
|
|
/**
|
|
|
|
|
* Route configuration for the bakery management application
|
|
|
|
|
*/
|
|
|
|
|
|
2025-09-09 07:32:59 +02:00
|
|
|
import { ROLE_COMBINATIONS } from '../types/roles';
|
|
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
export interface RouteConfig {
|
|
|
|
|
path: string;
|
|
|
|
|
name: string;
|
|
|
|
|
component: string;
|
|
|
|
|
title: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
icon?: string;
|
|
|
|
|
requiresAuth: boolean;
|
2025-11-06 18:39:20 +00:00
|
|
|
requiredRoles?: readonly string[];
|
|
|
|
|
requiredPermissions?: readonly string[];
|
2025-09-21 13:27:50 +02:00
|
|
|
requiredSubscriptionFeature?: string;
|
|
|
|
|
requiredAnalyticsLevel?: 'basic' | 'advanced' | 'predictive';
|
2025-08-28 10:41:04 +02:00
|
|
|
showInNavigation?: boolean;
|
|
|
|
|
showInBreadcrumbs?: boolean;
|
|
|
|
|
children?: RouteConfig[];
|
|
|
|
|
meta?: {
|
|
|
|
|
layout?: 'default' | 'auth' | 'minimal';
|
|
|
|
|
headerTitle?: string;
|
|
|
|
|
breadcrumbTitle?: string;
|
|
|
|
|
hideHeader?: boolean;
|
|
|
|
|
hideSidebar?: boolean;
|
|
|
|
|
fullScreen?: boolean;
|
|
|
|
|
scrollToTop?: boolean;
|
|
|
|
|
preload?: boolean;
|
|
|
|
|
cache?: boolean;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Route paths as constants
|
|
|
|
|
export const ROUTES = {
|
|
|
|
|
// Public routes
|
|
|
|
|
HOME: '/',
|
2025-11-07 12:00:01 +01:00
|
|
|
FEATURES: '/features',
|
2025-08-28 10:41:04 +02:00
|
|
|
LOGIN: '/login',
|
|
|
|
|
REGISTER: '/register',
|
|
|
|
|
FORGOT_PASSWORD: '/forgot-password',
|
|
|
|
|
RESET_PASSWORD: '/reset-password',
|
|
|
|
|
VERIFY_EMAIL: '/verify-email',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Dashboard
|
|
|
|
|
DASHBOARD: '/app/dashboard',
|
2025-11-27 15:52:40 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Inventory Management
|
2025-09-19 12:06:26 +02:00
|
|
|
INVENTORY: '/app/database/inventory',
|
2025-08-28 10:41:04 +02:00
|
|
|
INVENTORY_INGREDIENTS: '/inventory/ingredients',
|
|
|
|
|
INVENTORY_STOCK: '/inventory/stock',
|
|
|
|
|
INVENTORY_MOVEMENTS: '/inventory/movements',
|
|
|
|
|
INVENTORY_ALERTS: '/inventory/alerts',
|
|
|
|
|
INVENTORY_QUALITY: '/inventory/quality',
|
|
|
|
|
INVENTORY_REPORTS: '/inventory/reports',
|
2025-09-19 12:06:26 +02:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Production Management
|
|
|
|
|
PRODUCTION: '/app/operations/production',
|
|
|
|
|
PRODUCTION_BATCHES: '/production/batches',
|
|
|
|
|
PRODUCTION_RECIPES: '/production/recipes',
|
|
|
|
|
PRODUCTION_SCHEDULE: '/production/schedule',
|
|
|
|
|
PRODUCTION_QUALITY: '/production/quality',
|
|
|
|
|
PRODUCTION_REPORTS: '/production/reports',
|
2025-09-23 19:24:22 +02:00
|
|
|
PRODUCTION_ANALYTICS: '/app/analytics/production',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Sales & Analytics
|
|
|
|
|
SALES: '/sales',
|
|
|
|
|
SALES_DATA: '/sales/data',
|
|
|
|
|
SALES_ANALYTICS: '/sales/analytics',
|
|
|
|
|
SALES_REPORTS: '/sales/reports',
|
|
|
|
|
SALES_FORECASTING: '/sales/forecasting',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Forecasting & ML
|
|
|
|
|
FORECASTING: '/forecasting',
|
|
|
|
|
FORECASTING_MODELS: '/forecasting/models',
|
|
|
|
|
FORECASTING_PREDICTIONS: '/forecasting/predictions',
|
|
|
|
|
FORECASTING_TRAINING: '/forecasting/training',
|
|
|
|
|
FORECASTING_ANALYTICS: '/forecasting/analytics',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Orders Management
|
2025-09-19 12:06:26 +02:00
|
|
|
ORDERS: '/app/database/orders',
|
2025-08-28 10:41:04 +02:00
|
|
|
ORDERS_LIST: '/orders/list',
|
|
|
|
|
ORDERS_QUEUE: '/orders/queue',
|
|
|
|
|
ORDERS_HISTORY: '/orders/history',
|
|
|
|
|
ORDERS_CUSTOMERS: '/orders/customers',
|
2025-09-19 12:06:26 +02:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Procurement
|
2025-09-19 12:06:26 +02:00
|
|
|
PROCUREMENT: '/app/operations/procurement',
|
2025-08-28 10:41:04 +02:00
|
|
|
PROCUREMENT_ORDERS: '/procurement/orders',
|
|
|
|
|
PROCUREMENT_SUPPLIERS: '/procurement/suppliers',
|
|
|
|
|
PROCUREMENT_DELIVERIES: '/procurement/deliveries',
|
2025-10-02 13:20:30 +02:00
|
|
|
PROCUREMENT_ANALYTICS: '/app/analytics/procurement',
|
2025-09-19 12:06:26 +02:00
|
|
|
|
2025-12-05 20:07:01 +01:00
|
|
|
// Distribution
|
|
|
|
|
DISTRIBUTION: '/app/operations/distribution',
|
|
|
|
|
|
2025-09-19 12:06:26 +02:00
|
|
|
// Recipes
|
|
|
|
|
RECIPES: '/app/database/recipes',
|
|
|
|
|
|
|
|
|
|
// Suppliers
|
|
|
|
|
SUPPLIERS: '/app/database/suppliers',
|
|
|
|
|
|
2025-10-27 16:33:26 +01:00
|
|
|
// Sustainability
|
|
|
|
|
SUSTAINABILITY: '/app/database/sustainability',
|
|
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Point of Sale
|
2025-09-19 12:06:26 +02:00
|
|
|
POS: '/app/operations/pos',
|
2025-08-28 10:41:04 +02:00
|
|
|
POS_INTEGRATION: '/pos/integration',
|
|
|
|
|
POS_TRANSACTIONS: '/pos/transactions',
|
|
|
|
|
POS_WEBHOOKS: '/pos/webhooks',
|
|
|
|
|
POS_SETTINGS: '/pos/settings',
|
2025-11-02 20:24:44 +01:00
|
|
|
|
|
|
|
|
// Analytics
|
|
|
|
|
ANALYTICS_EVENTS: '/app/analytics/events',
|
|
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Training & ML
|
|
|
|
|
TRAINING: '/training',
|
|
|
|
|
TRAINING_MODELS: '/training/models',
|
|
|
|
|
TRAINING_JOBS: '/training/jobs',
|
|
|
|
|
TRAINING_EVALUATION: '/training/evaluation',
|
|
|
|
|
TRAINING_DATASETS: '/training/datasets',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Notifications
|
|
|
|
|
NOTIFICATIONS: '/notifications',
|
|
|
|
|
NOTIFICATIONS_LIST: '/notifications/list',
|
|
|
|
|
NOTIFICATIONS_TEMPLATES: '/notifications/templates',
|
|
|
|
|
NOTIFICATIONS_SETTINGS: '/notifications/settings',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Settings
|
|
|
|
|
SETTINGS: '/settings',
|
2025-10-24 13:05:04 +02:00
|
|
|
SETTINGS_PROFILE: '/app/settings/profile',
|
|
|
|
|
SETTINGS_BAKERY: '/app/settings/bakery',
|
2025-09-24 22:22:01 +02:00
|
|
|
SETTINGS_SUBSCRIPTION: '/app/settings/subscription',
|
|
|
|
|
SETTINGS_ORGANIZATIONS: '/app/settings/organizations',
|
2025-10-24 13:05:04 +02:00
|
|
|
// Legacy routes (will redirect)
|
|
|
|
|
SETTINGS_PERSONAL_INFO_OLD: '/app/settings/personal-info',
|
|
|
|
|
SETTINGS_COMMUNICATION_OLD: '/app/settings/communication-preferences',
|
|
|
|
|
SETTINGS_PRIVACY_OLD: '/app/settings/privacy',
|
|
|
|
|
SETTINGS_BAKERY_INFO_OLD: '/app/database/information',
|
|
|
|
|
SETTINGS_BAKERY_AJUSTES_OLD: '/app/database/ajustes',
|
2025-08-28 10:41:04 +02:00
|
|
|
SETTINGS_TENANT: '/settings/tenant',
|
|
|
|
|
SETTINGS_USERS: '/settings/users',
|
|
|
|
|
SETTINGS_PERMISSIONS: '/settings/permissions',
|
|
|
|
|
SETTINGS_INTEGRATIONS: '/settings/integrations',
|
|
|
|
|
SETTINGS_BILLING: '/settings/billing',
|
2025-09-19 12:06:26 +02:00
|
|
|
SETTINGS_TEAM: '/app/database/team',
|
2025-09-24 16:42:23 +02:00
|
|
|
QUALITY_TEMPLATES: '/app/database/quality-templates',
|
2025-10-16 07:28:04 +02:00
|
|
|
|
|
|
|
|
// Legal & Privacy Pages
|
|
|
|
|
PRIVACY_POLICY: '/privacy',
|
|
|
|
|
TERMS_OF_SERVICE: '/terms',
|
|
|
|
|
COOKIE_POLICY: '/cookies',
|
|
|
|
|
COOKIE_PREFERENCES: '/cookie-preferences',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Reports
|
|
|
|
|
REPORTS: '/reports',
|
|
|
|
|
REPORTS_PRODUCTION: '/reports/production',
|
|
|
|
|
REPORTS_INVENTORY: '/reports/inventory',
|
|
|
|
|
REPORTS_SALES: '/reports/sales',
|
|
|
|
|
REPORTS_FINANCIAL: '/reports/financial',
|
|
|
|
|
REPORTS_QUALITY: '/reports/quality',
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Help & Support
|
|
|
|
|
HELP: '/help',
|
|
|
|
|
HELP_DOCUMENTATION: '/help/docs',
|
|
|
|
|
HELP_TUTORIALS: '/help/tutorials',
|
|
|
|
|
HELP_SUPPORT: '/help/support',
|
|
|
|
|
HELP_FEEDBACK: '/help/feedback',
|
Implement Phase 1: Setup Wizard Foundation (Foundation & Architecture)
Created complete foundation for the bakery operations setup wizard that guides
users through post-onboarding configuration of suppliers, inventory, recipes,
quality standards, and team members.
**Core Components Created:**
1. SetupWizard.tsx - Main wizard orchestrator
- 7-step configuration (Welcome → Suppliers → Inventory → Recipes → Quality → Team → Completion)
- Weighted progress tracking (complex steps count more)
- Step state management with backend synchronization
- Auto-save and resume functionality
- Skip logic for optional steps
2. StepProgress.tsx - Progress visualization
- Responsive progress bar with weighted calculation
- Desktop: Full step indicators with descriptions
- Mobile: Horizontal scrolling step indicators
- Visual completion status (checkmarks for completed steps)
- Shows optional vs required steps
3. StepNavigation.tsx - Navigation controls
- Back/Skip/Continue buttons with smart enabling
- Conditional skip button (only for optional steps)
- Loading states during saves
- Contextual button text based on step
4. Placeholder Step Components (7 steps):
- WelcomeStep: Introduction with feature preview
- SuppliersSetupStep: Placeholder for Phase 2
- InventorySetupStep: Placeholder for Phase 2
- RecipesSetupStep: Placeholder for Phase 2
- QualitySetupStep: Placeholder for Phase 3
- TeamSetupStep: Placeholder for Phase 3
- CompletionStep: Success celebration
**Routing & Integration:**
- Added /app/setup route to routes.config.ts and AppRouter.tsx
- Created SetupPage wrapper component
- Integrated with OnboardingWizard CompletionStep
- Added "One More Thing" CTA after onboarding
- Choice: "Configurar Ahora (15 min)" or "Lo haré después"
- Smooth transition from onboarding to setup
**Key Features:**
✅ Weighted progress calculation (steps weighted by complexity/time)
✅ Mobile and desktop responsive design
✅ Step state persistence (save & resume)
✅ Skip logic for optional steps (Quality, Team)
✅ Backend integration ready (uses existing useUserProgress hooks)
✅ Consistent with existing OnboardingWizard patterns
✅ Loading and error states
✅ Accessibility support (ARIA labels, keyboard navigation ready)
**Architecture Decisions:**
- Reuses OnboardingWizard patterns (StepConfig interface, progress tracking)
- Integrates with existing backend (user_progress table, step completion API)
- AppShell layout (shows header & sidebar for context)
- Modular step components (easy to implement individually in Phases 2-3)
**Progress:**
Phase 1 (Foundation): ✅ COMPLETE
- Component structure ✅
- Navigation & progress ✅
- Routing & integration ✅
- Placeholder steps ✅
Phase 2 (Core Steps): 🔜 NEXT
- Suppliers setup implementation
- Inventory items setup implementation
- Recipes setup implementation
Phase 3 (Advanced Features): 🔜 FUTURE
- Quality standards implementation
- Team setup implementation
- Templates & smart defaults
**Files Changed:**
- 17 new files created
- 3 existing files modified (CompletionStep.tsx, AppRouter.tsx, routes.config.ts)
**Testing Status:**
- Components compile successfully
- No TypeScript errors
- Ready for Phase 2 implementation
Based on comprehensive design specification in:
- docs/wizard-flow-specification.md (2,144 lines)
- docs/jtbd-analysis-inventory-setup.md (461 lines)
Total implementation time: ~4 hours (Phase 1 of 6 phases)
Estimated total project: 11 weeks (Phase 1: Week 1-2 foundation ✅)
2025-11-06 11:14:09 +00:00
|
|
|
|
2025-11-09 09:22:08 +01:00
|
|
|
// Onboarding (Setup is now integrated into UnifiedOnboardingWizard)
|
Implement Phase 1: Setup Wizard Foundation (Foundation & Architecture)
Created complete foundation for the bakery operations setup wizard that guides
users through post-onboarding configuration of suppliers, inventory, recipes,
quality standards, and team members.
**Core Components Created:**
1. SetupWizard.tsx - Main wizard orchestrator
- 7-step configuration (Welcome → Suppliers → Inventory → Recipes → Quality → Team → Completion)
- Weighted progress tracking (complex steps count more)
- Step state management with backend synchronization
- Auto-save and resume functionality
- Skip logic for optional steps
2. StepProgress.tsx - Progress visualization
- Responsive progress bar with weighted calculation
- Desktop: Full step indicators with descriptions
- Mobile: Horizontal scrolling step indicators
- Visual completion status (checkmarks for completed steps)
- Shows optional vs required steps
3. StepNavigation.tsx - Navigation controls
- Back/Skip/Continue buttons with smart enabling
- Conditional skip button (only for optional steps)
- Loading states during saves
- Contextual button text based on step
4. Placeholder Step Components (7 steps):
- WelcomeStep: Introduction with feature preview
- SuppliersSetupStep: Placeholder for Phase 2
- InventorySetupStep: Placeholder for Phase 2
- RecipesSetupStep: Placeholder for Phase 2
- QualitySetupStep: Placeholder for Phase 3
- TeamSetupStep: Placeholder for Phase 3
- CompletionStep: Success celebration
**Routing & Integration:**
- Added /app/setup route to routes.config.ts and AppRouter.tsx
- Created SetupPage wrapper component
- Integrated with OnboardingWizard CompletionStep
- Added "One More Thing" CTA after onboarding
- Choice: "Configurar Ahora (15 min)" or "Lo haré después"
- Smooth transition from onboarding to setup
**Key Features:**
✅ Weighted progress calculation (steps weighted by complexity/time)
✅ Mobile and desktop responsive design
✅ Step state persistence (save & resume)
✅ Skip logic for optional steps (Quality, Team)
✅ Backend integration ready (uses existing useUserProgress hooks)
✅ Consistent with existing OnboardingWizard patterns
✅ Loading and error states
✅ Accessibility support (ARIA labels, keyboard navigation ready)
**Architecture Decisions:**
- Reuses OnboardingWizard patterns (StepConfig interface, progress tracking)
- Integrates with existing backend (user_progress table, step completion API)
- AppShell layout (shows header & sidebar for context)
- Modular step components (easy to implement individually in Phases 2-3)
**Progress:**
Phase 1 (Foundation): ✅ COMPLETE
- Component structure ✅
- Navigation & progress ✅
- Routing & integration ✅
- Placeholder steps ✅
Phase 2 (Core Steps): 🔜 NEXT
- Suppliers setup implementation
- Inventory items setup implementation
- Recipes setup implementation
Phase 3 (Advanced Features): 🔜 FUTURE
- Quality standards implementation
- Team setup implementation
- Templates & smart defaults
**Files Changed:**
- 17 new files created
- 3 existing files modified (CompletionStep.tsx, AppRouter.tsx, routes.config.ts)
**Testing Status:**
- Components compile successfully
- No TypeScript errors
- Ready for Phase 2 implementation
Based on comprehensive design specification in:
- docs/wizard-flow-specification.md (2,144 lines)
- docs/jtbd-analysis-inventory-setup.md (461 lines)
Total implementation time: ~4 hours (Phase 1 of 6 phases)
Estimated total project: 11 weeks (Phase 1: Week 1-2 foundation ✅)
2025-11-06 11:14:09 +00:00
|
|
|
ONBOARDING: '/app/onboarding',
|
|
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Error pages
|
|
|
|
|
NOT_FOUND: '/404',
|
|
|
|
|
UNAUTHORIZED: '/401',
|
|
|
|
|
FORBIDDEN: '/403',
|
|
|
|
|
SERVER_ERROR: '/500',
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
// Route configurations
|
|
|
|
|
export const routesConfig: RouteConfig[] = [
|
|
|
|
|
// Public routes
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.HOME,
|
|
|
|
|
name: 'Home',
|
|
|
|
|
component: 'HomePage',
|
2025-11-18 22:17:56 +01:00
|
|
|
title: 'BakeWise - Gestión Inteligente',
|
2025-08-28 10:41:04 +02:00
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'minimal',
|
|
|
|
|
scrollToTop: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.LOGIN,
|
|
|
|
|
name: 'Login',
|
|
|
|
|
component: 'LoginPage',
|
|
|
|
|
title: 'Iniciar Sesión',
|
|
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'auth',
|
|
|
|
|
hideHeader: true,
|
|
|
|
|
hideSidebar: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.REGISTER,
|
|
|
|
|
name: 'Register',
|
|
|
|
|
component: 'RegisterPage',
|
|
|
|
|
title: 'Crear Cuenta',
|
|
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'auth',
|
|
|
|
|
hideHeader: true,
|
|
|
|
|
hideSidebar: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
2025-11-07 12:00:01 +01:00
|
|
|
{
|
|
|
|
|
path: ROUTES.FEATURES,
|
|
|
|
|
name: 'Features',
|
|
|
|
|
component: 'FeaturesPage',
|
2025-11-18 22:17:56 +01:00
|
|
|
title: 'Funcionalidades - BakeWise',
|
2025-11-07 12:00:01 +01:00
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'minimal',
|
|
|
|
|
scrollToTop: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Dashboard
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.DASHBOARD,
|
|
|
|
|
name: 'Dashboard',
|
|
|
|
|
component: 'DashboardPage',
|
|
|
|
|
title: 'Panel de Control',
|
|
|
|
|
icon: 'dashboard',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
meta: {
|
|
|
|
|
headerTitle: 'Panel de Control',
|
|
|
|
|
preload: true,
|
|
|
|
|
cache: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
2025-08-28 17:15:29 +02:00
|
|
|
|
2025-09-19 12:06:26 +02:00
|
|
|
// Operations Section - Business Operations Only
|
2025-08-28 10:41:04 +02:00
|
|
|
{
|
2025-08-28 17:15:29 +02:00
|
|
|
path: '/app/operations',
|
|
|
|
|
name: 'Operations',
|
|
|
|
|
component: 'OperationsPage',
|
|
|
|
|
title: 'Operaciones',
|
|
|
|
|
icon: 'production',
|
2025-08-28 10:41:04 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
2025-08-28 17:15:29 +02:00
|
|
|
children: [
|
2025-09-19 12:06:26 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/operations/procurement',
|
|
|
|
|
name: 'Procurement',
|
|
|
|
|
component: 'ProcurementPage',
|
|
|
|
|
title: 'Compras',
|
|
|
|
|
icon: 'procurement',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-08-28 17:15:29 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/operations/production',
|
|
|
|
|
name: 'Production',
|
|
|
|
|
component: 'ProductionPage',
|
|
|
|
|
title: 'Producción',
|
|
|
|
|
icon: 'production',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-09-19 12:06:26 +02:00
|
|
|
path: '/app/operations/pos',
|
|
|
|
|
name: 'POS',
|
|
|
|
|
component: 'POSPage',
|
|
|
|
|
title: 'Punto de Venta',
|
|
|
|
|
icon: 'pos',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-12-05 20:07:01 +01:00
|
|
|
{
|
|
|
|
|
path: '/app/operations/distribution',
|
|
|
|
|
name: 'Distribution',
|
|
|
|
|
component: 'DistributionPage',
|
|
|
|
|
title: 'Distribución',
|
2026-01-01 19:01:33 +01:00
|
|
|
icon: 'distribution',
|
2025-12-05 20:07:01 +01:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
requiredSubscriptionFeature: 'distribution',
|
|
|
|
|
},
|
2025-09-19 12:06:26 +02:00
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
|
2025-09-24 22:22:01 +02:00
|
|
|
// Analytics Section - Subscription protected
|
|
|
|
|
{
|
|
|
|
|
path: '/app/analytics',
|
|
|
|
|
name: 'Analytics',
|
|
|
|
|
component: 'AnalyticsPage',
|
|
|
|
|
title: 'Análisis',
|
2025-11-05 13:34:56 +01:00
|
|
|
icon: 'analytics',
|
2025-09-24 22:22:01 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
|
|
|
|
requiredAnalyticsLevel: 'basic',
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
path: '/app/analytics/production',
|
|
|
|
|
name: 'ProductionAnalytics',
|
|
|
|
|
component: 'ProductionAnalyticsPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Dashboard de Producción',
|
2025-09-24 22:22:01 +02:00
|
|
|
icon: 'production',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
|
|
|
|
requiredAnalyticsLevel: 'advanced',
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-10-02 13:20:30 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/analytics/procurement',
|
|
|
|
|
name: 'ProcurementAnalytics',
|
|
|
|
|
component: 'ProcurementAnalyticsPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Dashboard de Compras',
|
2025-10-02 13:20:30 +02:00
|
|
|
icon: 'procurement',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
|
|
|
|
requiredAnalyticsLevel: 'advanced',
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-09-24 22:22:01 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/analytics/forecasting',
|
|
|
|
|
name: 'Forecasting',
|
|
|
|
|
component: 'ForecastingPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Predicciones',
|
2025-09-24 22:22:01 +02:00
|
|
|
icon: 'forecasting',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
|
|
|
|
requiredAnalyticsLevel: 'advanced',
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/app/analytics/sales',
|
|
|
|
|
name: 'SalesAnalytics',
|
|
|
|
|
component: 'SalesAnalyticsPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Dashboard de Ventas',
|
2025-09-24 22:22:01 +02:00
|
|
|
icon: 'sales',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
|
|
|
|
requiredAnalyticsLevel: 'advanced',
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/app/analytics/performance',
|
|
|
|
|
name: 'PerformanceAnalytics',
|
|
|
|
|
component: 'PerformanceAnalyticsPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'KPIs Generales',
|
|
|
|
|
icon: 'performance',
|
2025-09-24 22:22:01 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
|
|
|
|
requiredAnalyticsLevel: 'advanced',
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-10-07 07:15:07 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/analytics/scenario-simulation',
|
|
|
|
|
name: 'ScenarioSimulation',
|
|
|
|
|
component: 'ScenarioSimulationPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Análisis What-If',
|
|
|
|
|
icon: 'simulation',
|
2025-10-07 07:15:07 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
2025-10-15 21:09:42 +02:00
|
|
|
requiredAnalyticsLevel: 'advanced',
|
2025-10-07 07:15:07 +02:00
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-09-24 22:22:01 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/analytics/ai-insights',
|
|
|
|
|
name: 'AIInsights',
|
|
|
|
|
component: 'AIInsightsPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Recomendaciones',
|
|
|
|
|
icon: 'insights',
|
2025-09-24 22:22:01 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
2025-12-15 21:14:22 +01:00
|
|
|
requiredAnalyticsLevel: 'advanced', // Available for Professional and Enterprise tiers
|
2025-09-24 22:22:01 +02:00
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-11-02 20:24:44 +01:00
|
|
|
{
|
|
|
|
|
path: '/app/analytics/events',
|
|
|
|
|
name: 'EventRegistry',
|
|
|
|
|
component: 'EventRegistryPage',
|
2025-11-05 13:34:56 +01:00
|
|
|
title: 'Eventos del Sistema',
|
|
|
|
|
icon: 'events',
|
2025-11-02 20:24:44 +01:00
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ['admin', 'owner'],
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-09-24 22:22:01 +02:00
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
|
2025-09-19 12:06:26 +02:00
|
|
|
// Catalog Section - Current Bakery Status
|
|
|
|
|
{
|
|
|
|
|
path: '/app/database',
|
|
|
|
|
name: 'Database',
|
|
|
|
|
component: 'DatabasePage',
|
|
|
|
|
title: 'Mi Panadería',
|
|
|
|
|
icon: 'database',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
children: [
|
2025-10-23 07:44:54 +02:00
|
|
|
{
|
2025-10-24 13:05:04 +02:00
|
|
|
path: '/app/settings/bakery',
|
|
|
|
|
name: 'BakerySettings',
|
|
|
|
|
component: 'BakerySettingsPage',
|
2025-10-23 07:44:54 +02:00
|
|
|
title: 'Ajustes',
|
|
|
|
|
icon: 'settings',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
requiredRoles: ROLE_COMBINATIONS.ADMIN_ACCESS,
|
2025-08-28 17:15:29 +02:00
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-09-19 12:06:26 +02:00
|
|
|
path: '/app/database/suppliers',
|
|
|
|
|
name: 'Suppliers',
|
|
|
|
|
component: 'SuppliersPage',
|
|
|
|
|
title: 'Proveedores',
|
|
|
|
|
icon: 'procurement',
|
2025-08-28 17:15:29 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-09-19 12:06:26 +02:00
|
|
|
path: '/app/database/inventory',
|
|
|
|
|
name: 'Inventory',
|
|
|
|
|
component: 'InventoryPage',
|
|
|
|
|
title: 'Inventario',
|
|
|
|
|
icon: 'inventory',
|
2025-08-28 17:15:29 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
2025-09-26 12:12:17 +02:00
|
|
|
},
|
2025-12-05 20:07:01 +01:00
|
|
|
{
|
2025-09-26 12:12:17 +02:00
|
|
|
path: '/app/database/recipes',
|
|
|
|
|
name: 'Recipes',
|
|
|
|
|
component: 'RecipesPage',
|
|
|
|
|
title: 'Recetas',
|
2025-10-27 16:33:26 +01:00
|
|
|
icon: 'chef-hat',
|
2025-09-26 12:12:17 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/app/database/orders',
|
|
|
|
|
name: 'Orders',
|
|
|
|
|
component: 'OrdersPage',
|
|
|
|
|
title: 'Pedidos',
|
|
|
|
|
icon: 'orders',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
2025-08-28 17:15:29 +02:00
|
|
|
},
|
2025-09-23 19:24:22 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/database/maquinaria',
|
|
|
|
|
name: 'Maquinaria',
|
|
|
|
|
component: 'MaquinariaPage',
|
|
|
|
|
title: 'Maquinaria',
|
2025-10-27 16:33:26 +01:00
|
|
|
icon: 'cog',
|
2025-09-23 19:24:22 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-08-28 17:15:29 +02:00
|
|
|
{
|
2025-09-26 12:12:17 +02:00
|
|
|
path: '/app/database/quality-templates',
|
|
|
|
|
name: 'QualityTemplates',
|
|
|
|
|
component: 'QualityTemplatesPage',
|
|
|
|
|
title: 'Plantillas de Calidad',
|
2025-10-27 16:33:26 +01:00
|
|
|
icon: 'clipboard-check',
|
2025-08-28 17:15:29 +02:00
|
|
|
requiresAuth: true,
|
2025-09-26 12:12:17 +02:00
|
|
|
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
|
2025-08-28 17:15:29 +02:00
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-09-09 21:39:12 +02:00
|
|
|
{
|
2025-09-19 12:06:26 +02:00
|
|
|
path: '/app/database/team',
|
|
|
|
|
name: 'Team',
|
|
|
|
|
component: 'TeamPage',
|
2025-09-25 12:14:46 +02:00
|
|
|
title: 'Trabajadores',
|
2025-09-19 12:06:26 +02:00
|
|
|
icon: 'user',
|
2025-09-09 21:39:12 +02:00
|
|
|
requiresAuth: true,
|
2025-09-19 12:06:26 +02:00
|
|
|
requiredRoles: ROLE_COMBINATIONS.ADMIN_ACCESS,
|
2025-09-09 21:39:12 +02:00
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-09-20 22:11:05 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/database/models',
|
|
|
|
|
name: 'ModelsConfig',
|
|
|
|
|
component: 'ModelsConfigPage',
|
|
|
|
|
title: 'Modelos IA',
|
2025-10-27 16:33:26 +01:00
|
|
|
icon: 'brain-circuit',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/app/database/sustainability',
|
|
|
|
|
name: 'Sustainability',
|
|
|
|
|
component: 'SustainabilityPage',
|
|
|
|
|
title: 'Sostenibilidad',
|
|
|
|
|
icon: 'leaf',
|
2025-09-20 22:11:05 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
2025-09-26 12:12:17 +02:00
|
|
|
}
|
2025-08-28 17:15:29 +02:00
|
|
|
],
|
2025-08-28 10:41:04 +02:00
|
|
|
},
|
2025-08-28 17:15:29 +02:00
|
|
|
|
2025-11-27 15:52:40 +01:00
|
|
|
|
2025-09-24 22:22:01 +02:00
|
|
|
// Settings Section
|
2025-08-28 10:41:04 +02:00
|
|
|
{
|
2025-09-24 22:22:01 +02:00
|
|
|
path: '/app/settings',
|
|
|
|
|
name: 'Settings',
|
|
|
|
|
component: 'SettingsPage',
|
|
|
|
|
title: 'Mi Perfil',
|
|
|
|
|
icon: 'user',
|
2025-08-28 10:41:04 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
2025-08-28 17:15:29 +02:00
|
|
|
children: [
|
2025-09-23 19:24:22 +02:00
|
|
|
{
|
2025-10-24 13:05:04 +02:00
|
|
|
path: '/app/settings/profile',
|
|
|
|
|
name: 'Profile',
|
|
|
|
|
component: 'NewProfileSettingsPage',
|
|
|
|
|
title: 'Ajustes',
|
2025-09-24 22:22:01 +02:00
|
|
|
icon: 'user',
|
2025-08-28 17:15:29 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-09-24 22:22:01 +02:00
|
|
|
path: '/app/settings/subscription',
|
|
|
|
|
name: 'Subscription',
|
|
|
|
|
component: 'SubscriptionPage',
|
|
|
|
|
title: 'Suscripción',
|
|
|
|
|
icon: 'credit-card',
|
2025-08-28 23:40:44 +02:00
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-09-22 11:04:03 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/settings/organizations',
|
|
|
|
|
name: 'Organizations',
|
|
|
|
|
component: 'OrganizationsPage',
|
2025-09-25 12:14:46 +02:00
|
|
|
title: 'Establecimientos',
|
2025-09-22 11:04:03 +02:00
|
|
|
icon: 'database',
|
|
|
|
|
requiresAuth: true,
|
|
|
|
|
showInNavigation: true,
|
|
|
|
|
showInBreadcrumbs: true,
|
|
|
|
|
},
|
2025-08-28 10:41:04 +02:00
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
|
2025-09-03 14:06:38 +02:00
|
|
|
// Onboarding Section - Complete 9-step flow
|
2025-08-28 10:41:04 +02:00
|
|
|
{
|
|
|
|
|
path: '/app/onboarding',
|
|
|
|
|
name: 'Onboarding',
|
|
|
|
|
component: 'OnboardingPage',
|
|
|
|
|
title: 'Configuración Inicial',
|
2025-09-03 14:06:38 +02:00
|
|
|
description: 'Configuración completa en 9 pasos con IA',
|
2025-08-28 10:41:04 +02:00
|
|
|
icon: 'settings',
|
|
|
|
|
requiresAuth: true,
|
2025-09-01 08:19:54 +02:00
|
|
|
showInNavigation: false,
|
2025-09-03 14:06:38 +02:00
|
|
|
meta: {
|
|
|
|
|
hideHeader: true,
|
|
|
|
|
hideSidebar: true,
|
|
|
|
|
fullScreen: true,
|
|
|
|
|
},
|
2025-08-28 10:41:04 +02:00
|
|
|
},
|
|
|
|
|
|
2025-11-09 09:22:08 +01:00
|
|
|
// Setup is now integrated into UnifiedOnboardingWizard - route removed
|
Implement Phase 1: Setup Wizard Foundation (Foundation & Architecture)
Created complete foundation for the bakery operations setup wizard that guides
users through post-onboarding configuration of suppliers, inventory, recipes,
quality standards, and team members.
**Core Components Created:**
1. SetupWizard.tsx - Main wizard orchestrator
- 7-step configuration (Welcome → Suppliers → Inventory → Recipes → Quality → Team → Completion)
- Weighted progress tracking (complex steps count more)
- Step state management with backend synchronization
- Auto-save and resume functionality
- Skip logic for optional steps
2. StepProgress.tsx - Progress visualization
- Responsive progress bar with weighted calculation
- Desktop: Full step indicators with descriptions
- Mobile: Horizontal scrolling step indicators
- Visual completion status (checkmarks for completed steps)
- Shows optional vs required steps
3. StepNavigation.tsx - Navigation controls
- Back/Skip/Continue buttons with smart enabling
- Conditional skip button (only for optional steps)
- Loading states during saves
- Contextual button text based on step
4. Placeholder Step Components (7 steps):
- WelcomeStep: Introduction with feature preview
- SuppliersSetupStep: Placeholder for Phase 2
- InventorySetupStep: Placeholder for Phase 2
- RecipesSetupStep: Placeholder for Phase 2
- QualitySetupStep: Placeholder for Phase 3
- TeamSetupStep: Placeholder for Phase 3
- CompletionStep: Success celebration
**Routing & Integration:**
- Added /app/setup route to routes.config.ts and AppRouter.tsx
- Created SetupPage wrapper component
- Integrated with OnboardingWizard CompletionStep
- Added "One More Thing" CTA after onboarding
- Choice: "Configurar Ahora (15 min)" or "Lo haré después"
- Smooth transition from onboarding to setup
**Key Features:**
✅ Weighted progress calculation (steps weighted by complexity/time)
✅ Mobile and desktop responsive design
✅ Step state persistence (save & resume)
✅ Skip logic for optional steps (Quality, Team)
✅ Backend integration ready (uses existing useUserProgress hooks)
✅ Consistent with existing OnboardingWizard patterns
✅ Loading and error states
✅ Accessibility support (ARIA labels, keyboard navigation ready)
**Architecture Decisions:**
- Reuses OnboardingWizard patterns (StepConfig interface, progress tracking)
- Integrates with existing backend (user_progress table, step completion API)
- AppShell layout (shows header & sidebar for context)
- Modular step components (easy to implement individually in Phases 2-3)
**Progress:**
Phase 1 (Foundation): ✅ COMPLETE
- Component structure ✅
- Navigation & progress ✅
- Routing & integration ✅
- Placeholder steps ✅
Phase 2 (Core Steps): 🔜 NEXT
- Suppliers setup implementation
- Inventory items setup implementation
- Recipes setup implementation
Phase 3 (Advanced Features): 🔜 FUTURE
- Quality standards implementation
- Team setup implementation
- Templates & smart defaults
**Files Changed:**
- 17 new files created
- 3 existing files modified (CompletionStep.tsx, AppRouter.tsx, routes.config.ts)
**Testing Status:**
- Components compile successfully
- No TypeScript errors
- Ready for Phase 2 implementation
Based on comprehensive design specification in:
- docs/wizard-flow-specification.md (2,144 lines)
- docs/jtbd-analysis-inventory-setup.md (461 lines)
Total implementation time: ~4 hours (Phase 1 of 6 phases)
Estimated total project: 11 weeks (Phase 1: Week 1-2 foundation ✅)
2025-11-06 11:14:09 +00:00
|
|
|
|
|
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Error pages
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.NOT_FOUND,
|
|
|
|
|
name: 'NotFound',
|
|
|
|
|
component: 'NotFoundPage',
|
|
|
|
|
title: 'Página no encontrada',
|
|
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'minimal',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.UNAUTHORIZED,
|
|
|
|
|
name: 'Unauthorized',
|
|
|
|
|
component: 'UnauthorizedPage',
|
|
|
|
|
title: 'No autorizado',
|
|
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'minimal',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: ROUTES.FORBIDDEN,
|
|
|
|
|
name: 'Forbidden',
|
|
|
|
|
component: 'ForbiddenPage',
|
|
|
|
|
title: 'Acceso prohibido',
|
|
|
|
|
requiresAuth: false,
|
|
|
|
|
showInNavigation: false,
|
|
|
|
|
meta: {
|
|
|
|
|
layout: 'minimal',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Helper functions
|
|
|
|
|
export const getRouteByPath = (path: string): RouteConfig | undefined => {
|
|
|
|
|
const findRoute = (routes: RouteConfig[], targetPath: string): RouteConfig | undefined => {
|
|
|
|
|
for (const route of routes) {
|
|
|
|
|
if (route.path === targetPath) {
|
|
|
|
|
return route;
|
|
|
|
|
}
|
|
|
|
|
if (route.children) {
|
|
|
|
|
const childRoute = findRoute(route.children, targetPath);
|
|
|
|
|
if (childRoute) {
|
|
|
|
|
return childRoute;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
};
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
return findRoute(routesConfig, path);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getRouteByName = (name: string): RouteConfig | undefined => {
|
|
|
|
|
const findRoute = (routes: RouteConfig[], targetName: string): RouteConfig | undefined => {
|
|
|
|
|
for (const route of routes) {
|
|
|
|
|
if (route.name === targetName) {
|
|
|
|
|
return route;
|
|
|
|
|
}
|
|
|
|
|
if (route.children) {
|
|
|
|
|
const childRoute = findRoute(route.children, targetName);
|
|
|
|
|
if (childRoute) {
|
|
|
|
|
return childRoute;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
};
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
return findRoute(routesConfig, name);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getNavigationRoutes = (): RouteConfig[] => {
|
|
|
|
|
const filterNavRoutes = (routes: RouteConfig[]): RouteConfig[] => {
|
|
|
|
|
return routes
|
|
|
|
|
.filter(route => route.showInNavigation)
|
|
|
|
|
.map(route => ({
|
|
|
|
|
...route,
|
|
|
|
|
children: route.children ? filterNavRoutes(route.children) : undefined,
|
|
|
|
|
}));
|
|
|
|
|
};
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
return filterNavRoutes(routesConfig);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getBreadcrumbs = (path: string): RouteConfig[] => {
|
|
|
|
|
const breadcrumbs: RouteConfig[] = [];
|
|
|
|
|
const pathSegments = path.split('/').filter(segment => segment);
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
let currentPath = '';
|
|
|
|
|
for (const segment of pathSegments) {
|
|
|
|
|
currentPath += `/${segment}`;
|
|
|
|
|
const route = getRouteByPath(currentPath);
|
|
|
|
|
if (route && route.showInBreadcrumbs !== false) {
|
|
|
|
|
breadcrumbs.push(route);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
return breadcrumbs;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const hasPermission = (route: RouteConfig, userPermissions: string[]): boolean => {
|
|
|
|
|
if (!route.requiredPermissions || route.requiredPermissions.length === 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Check for wildcard permission
|
|
|
|
|
if (userPermissions.includes('*')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
|
|
|
|
return route.requiredPermissions.every(permission =>
|
2025-08-28 10:41:04 +02:00
|
|
|
userPermissions.includes(permission)
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const hasRole = (route: RouteConfig, userRoles: string[]): boolean => {
|
|
|
|
|
if (!route.requiredRoles || route.requiredRoles.length === 0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
|
|
|
|
return route.requiredRoles.some(role =>
|
2025-08-28 10:41:04 +02:00
|
|
|
userRoles.includes(role)
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const canAccessRoute = (
|
2025-12-05 20:07:01 +01:00
|
|
|
route: RouteConfig,
|
|
|
|
|
isAuthenticated: boolean,
|
|
|
|
|
userRoles: string[] = [],
|
2025-08-28 10:41:04 +02:00
|
|
|
userPermissions: string[] = []
|
|
|
|
|
): boolean => {
|
|
|
|
|
// Check authentication requirement
|
|
|
|
|
if (route.requiresAuth && !isAuthenticated) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Check role requirements
|
|
|
|
|
if (!hasRole(route, userRoles)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
// Check permission requirements
|
|
|
|
|
if (!hasPermission(route, userPermissions)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-12-05 20:07:01 +01:00
|
|
|
|
2025-08-28 10:41:04 +02:00
|
|
|
return true;
|
|
|
|
|
};
|