Files
bakery-ia/frontend/src/router/routes.config.ts

647 lines
16 KiB
TypeScript
Raw Normal View History

2025-08-28 10:41:04 +02:00
/**
* Route configuration for the bakery management application
*/
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;
requiredRoles?: string[];
requiredPermissions?: 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: '/',
LOGIN: '/login',
REGISTER: '/register',
FORGOT_PASSWORD: '/forgot-password',
RESET_PASSWORD: '/reset-password',
VERIFY_EMAIL: '/verify-email',
// Dashboard
DASHBOARD: '/app/dashboard',
// 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',
// Sales & Analytics
SALES: '/sales',
SALES_DATA: '/sales/data',
SALES_ANALYTICS: '/sales/analytics',
SALES_REPORTS: '/sales/reports',
SALES_FORECASTING: '/sales/forecasting',
// Forecasting & ML
FORECASTING: '/forecasting',
FORECASTING_MODELS: '/forecasting/models',
FORECASTING_PREDICTIONS: '/forecasting/predictions',
FORECASTING_TRAINING: '/forecasting/training',
FORECASTING_ANALYTICS: '/forecasting/analytics',
// 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',
PROCUREMENT_ANALYTICS: '/procurement/analytics',
2025-09-19 12:06:26 +02:00
// Recipes
RECIPES: '/app/database/recipes',
// Suppliers
SUPPLIERS: '/app/database/suppliers',
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',
// Data Management
2025-09-19 12:06:26 +02:00
DATA: '/app/data',
2025-08-28 10:41:04 +02:00
DATA_IMPORT: '/data/import',
DATA_EXPORT: '/data/export',
DATA_EXTERNAL: '/data/external',
2025-09-19 12:06:26 +02:00
DATA_WEATHER: '/app/data/weather',
DATA_EVENTS: '/app/data/events',
DATA_TRAFFIC: '/app/data/traffic',
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',
// Notifications
NOTIFICATIONS: '/notifications',
NOTIFICATIONS_LIST: '/notifications/list',
NOTIFICATIONS_TEMPLATES: '/notifications/templates',
NOTIFICATIONS_SETTINGS: '/notifications/settings',
// Settings
SETTINGS: '/settings',
2025-09-19 12:06:26 +02:00
SETTINGS_PROFILE: '/app/settings/profile',
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_BAKERY_CONFIG: '/app/database/bakery-config',
SETTINGS_TEAM: '/app/database/team',
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',
// Help & Support
HELP: '/help',
HELP_DOCUMENTATION: '/help/docs',
HELP_TUTORIALS: '/help/tutorials',
HELP_SUPPORT: '/help/support',
HELP_FEEDBACK: '/help/feedback',
// 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',
title: 'Panadería IA - Gestión Inteligente',
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,
},
},
// 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,
},
],
},
// Catalog Section - Current Bakery Status
{
path: '/app/database',
name: 'Database',
component: 'DatabasePage',
title: 'Mi Panadería',
icon: 'database',
requiresAuth: true,
showInNavigation: true,
children: [
{
path: '/app/database/recipes',
name: 'Recipes',
component: 'RecipesPage',
title: 'Recetas',
icon: 'production',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/database/orders',
2025-08-28 17:15:29 +02:00
name: 'Orders',
component: 'OrdersPage',
title: 'Pedidos',
icon: 'orders',
requiresAuth: true,
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-19 12:06:26 +02:00
path: '/app/database/bakery-config',
name: 'BakeryConfig',
component: 'BakeryConfigPage',
title: 'Configuración de Panadería',
icon: 'settings',
2025-08-28 17:15:29 +02:00
requiresAuth: true,
2025-09-19 12:06:26 +02:00
requiredRoles: ROLE_COMBINATIONS.ADMIN_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',
title: 'Gestión de Equipo',
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',
icon: 'training',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
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-09-21 13:27:50 +02:00
// Analytics Section - Subscription protected
2025-08-28 10:41:04 +02:00
{
2025-08-28 17:15:29 +02:00
path: '/app/analytics',
name: 'Analytics',
component: 'AnalyticsPage',
title: 'Analytics',
icon: 'sales',
2025-08-28 10:41:04 +02:00
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
2025-09-21 13:27:50 +02:00
requiredAnalyticsLevel: 'basic',
2025-08-28 10:41:04 +02:00
showInNavigation: true,
2025-08-28 17:15:29 +02:00
children: [
{
path: '/app/analytics/forecasting',
name: 'Forecasting',
component: 'ForecastingPage',
title: 'Pronósticos',
icon: 'forecasting',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
2025-09-21 13:27:50 +02:00
requiredAnalyticsLevel: 'advanced',
2025-08-28 17:15:29 +02:00
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/analytics/sales',
name: 'SalesAnalytics',
component: 'SalesAnalyticsPage',
title: 'Análisis de Ventas',
icon: 'sales',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
2025-09-21 13:27:50 +02:00
requiredAnalyticsLevel: 'advanced',
2025-08-28 17:15:29 +02:00
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/analytics/performance',
name: 'PerformanceAnalytics',
component: 'PerformanceAnalyticsPage',
title: 'Análisis de Rendimiento',
icon: 'sales',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
2025-09-21 13:27:50 +02:00
requiredAnalyticsLevel: 'advanced',
2025-08-28 17:15:29 +02:00
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/analytics/ai-insights',
name: 'AIInsights',
component: 'AIInsightsPage',
title: 'Insights de IA',
icon: 'forecasting',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.MANAGEMENT_ACCESS,
2025-09-21 13:27:50 +02:00
requiredAnalyticsLevel: 'predictive',
2025-08-28 17:15:29 +02:00
showInNavigation: true,
showInBreadcrumbs: true,
},
],
2025-08-28 10:41:04 +02:00
},
2025-08-28 17:15:29 +02:00
// Settings Section
2025-08-28 10:41:04 +02:00
{
2025-08-28 17:15:29 +02:00
path: '/app/settings',
2025-08-28 10:41:04 +02:00
name: 'Settings',
component: 'SettingsPage',
title: 'Configuración',
icon: 'settings',
requiresAuth: true,
showInNavigation: true,
children: [
2025-08-28 23:40:44 +02:00
{
path: '/app/settings/profile',
name: 'Profile',
component: 'ProfilePage',
title: 'Mi Perfil',
icon: 'user',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
2025-08-28 10:41:04 +02:00
],
},
// Data Management Section
{
path: '/app/data',
name: 'Data',
component: 'DataPage',
title: 'Gestión de Datos',
icon: 'data',
requiresAuth: true,
showInNavigation: true,
children: [
{
path: '/app/data/weather',
name: 'Weather',
component: 'WeatherPage',
title: 'Datos Meteorológicos',
icon: 'data',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/data/traffic',
name: 'Traffic',
component: 'TrafficPage',
title: 'Datos de Tráfico',
icon: 'data',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/data/events',
name: 'Events',
component: 'EventsPage',
title: 'Eventos y Festivales',
icon: 'data',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
],
},
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
},
// 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;
};
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;
};
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,
}));
};
return filterNavRoutes(routesConfig);
};
export const getBreadcrumbs = (path: string): RouteConfig[] => {
const breadcrumbs: RouteConfig[] = [];
const pathSegments = path.split('/').filter(segment => segment);
let currentPath = '';
for (const segment of pathSegments) {
currentPath += `/${segment}`;
const route = getRouteByPath(currentPath);
if (route && route.showInBreadcrumbs !== false) {
breadcrumbs.push(route);
}
}
return breadcrumbs;
};
export const hasPermission = (route: RouteConfig, userPermissions: string[]): boolean => {
if (!route.requiredPermissions || route.requiredPermissions.length === 0) {
return true;
}
// Check for wildcard permission
if (userPermissions.includes('*')) {
return true;
}
return route.requiredPermissions.every(permission =>
userPermissions.includes(permission)
);
};
export const hasRole = (route: RouteConfig, userRoles: string[]): boolean => {
if (!route.requiredRoles || route.requiredRoles.length === 0) {
return true;
}
return route.requiredRoles.some(role =>
userRoles.includes(role)
);
};
export const canAccessRoute = (
route: RouteConfig,
isAuthenticated: boolean,
userRoles: string[] = [],
userPermissions: string[] = []
): boolean => {
// Check authentication requirement
if (route.requiresAuth && !isAuthenticated) {
return false;
}
// Check role requirements
if (!hasRole(route, userRoles)) {
return false;
}
// Check permission requirements
if (!hasPermission(route, userPermissions)) {
return false;
}
return true;
};