ADD new frontend
This commit is contained in:
652
frontend/src/router/routes.config.ts
Normal file
652
frontend/src/router/routes.config.ts
Normal file
@@ -0,0 +1,652 @@
|
||||
/**
|
||||
* Route configuration for the bakery management application
|
||||
*/
|
||||
|
||||
export interface RouteConfig {
|
||||
path: string;
|
||||
name: string;
|
||||
component: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
requiresAuth: boolean;
|
||||
requiredRoles?: string[];
|
||||
requiredPermissions?: string[];
|
||||
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
|
||||
INVENTORY: '/app/operations/inventory',
|
||||
INVENTORY_INGREDIENTS: '/inventory/ingredients',
|
||||
INVENTORY_STOCK: '/inventory/stock',
|
||||
INVENTORY_MOVEMENTS: '/inventory/movements',
|
||||
INVENTORY_ALERTS: '/inventory/alerts',
|
||||
INVENTORY_QUALITY: '/inventory/quality',
|
||||
INVENTORY_REPORTS: '/inventory/reports',
|
||||
|
||||
// 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
|
||||
ORDERS: '/orders',
|
||||
ORDERS_LIST: '/orders/list',
|
||||
ORDERS_QUEUE: '/orders/queue',
|
||||
ORDERS_HISTORY: '/orders/history',
|
||||
ORDERS_CUSTOMERS: '/orders/customers',
|
||||
|
||||
// Procurement
|
||||
PROCUREMENT: '/procurement',
|
||||
PROCUREMENT_ORDERS: '/procurement/orders',
|
||||
PROCUREMENT_SUPPLIERS: '/procurement/suppliers',
|
||||
PROCUREMENT_DELIVERIES: '/procurement/deliveries',
|
||||
PROCUREMENT_ANALYTICS: '/procurement/analytics',
|
||||
|
||||
// Point of Sale
|
||||
POS: '/pos',
|
||||
POS_INTEGRATION: '/pos/integration',
|
||||
POS_TRANSACTIONS: '/pos/transactions',
|
||||
POS_WEBHOOKS: '/pos/webhooks',
|
||||
POS_SETTINGS: '/pos/settings',
|
||||
|
||||
// Data Management
|
||||
DATA: '/data',
|
||||
DATA_IMPORT: '/data/import',
|
||||
DATA_EXPORT: '/data/export',
|
||||
DATA_EXTERNAL: '/data/external',
|
||||
DATA_WEATHER: '/data/weather',
|
||||
DATA_EVENTS: '/data/events',
|
||||
|
||||
// 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',
|
||||
SETTINGS_PROFILE: '/settings/profile',
|
||||
SETTINGS_TENANT: '/settings/tenant',
|
||||
SETTINGS_USERS: '/settings/users',
|
||||
SETTINGS_PERMISSIONS: '/settings/permissions',
|
||||
SETTINGS_INTEGRATIONS: '/settings/integrations',
|
||||
SETTINGS_PREFERENCES: '/settings/preferences',
|
||||
SETTINGS_BILLING: '/settings/billing',
|
||||
|
||||
// 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,
|
||||
},
|
||||
},
|
||||
|
||||
// Inventory Management
|
||||
{
|
||||
path: '/app/operations/inventory',
|
||||
name: 'Inventory',
|
||||
component: 'InventoryPage',
|
||||
title: 'Inventario',
|
||||
icon: 'inventory',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
|
||||
// Production Management
|
||||
{
|
||||
path: '/app/operations/production',
|
||||
name: 'Production',
|
||||
component: 'ProductionPage',
|
||||
title: 'Producción',
|
||||
icon: 'production',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
// Settings
|
||||
{
|
||||
path: ROUTES.SETTINGS,
|
||||
name: 'Settings',
|
||||
component: 'SettingsPage',
|
||||
title: 'Configuración',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
children: [
|
||||
{
|
||||
path: '/app/settings/bakery-config',
|
||||
name: 'BakeryConfig',
|
||||
component: 'BakeryConfigPage',
|
||||
title: 'Configuración de Panadería',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/settings/system',
|
||||
name: 'SystemSettings',
|
||||
component: 'SystemSettingsPage',
|
||||
title: 'Configuración del Sistema',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/settings/team',
|
||||
name: 'Team',
|
||||
component: 'TeamPage',
|
||||
title: 'Gestión de Equipo',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/settings/training',
|
||||
name: 'Training',
|
||||
component: 'TrainingPage',
|
||||
title: 'Entrenamiento',
|
||||
icon: 'training',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Individual Operations Pages
|
||||
{
|
||||
path: '/app/operations/recipes',
|
||||
name: 'Recipes',
|
||||
component: 'RecipesPage',
|
||||
title: 'Recetas',
|
||||
icon: 'production',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
{
|
||||
path: '/app/operations/orders',
|
||||
name: 'Orders',
|
||||
component: 'OrdersPage',
|
||||
title: 'Pedidos',
|
||||
icon: 'orders',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
{
|
||||
path: '/app/operations/procurement',
|
||||
name: 'Procurement',
|
||||
component: 'ProcurementPage',
|
||||
title: 'Compras',
|
||||
icon: 'procurement',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
{
|
||||
path: '/app/operations/pos',
|
||||
name: 'POS',
|
||||
component: 'POSPage',
|
||||
title: 'Punto de Venta',
|
||||
icon: 'pos',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
|
||||
// Individual Analytics Pages
|
||||
{
|
||||
path: '/app/analytics/forecasting',
|
||||
name: 'Forecasting',
|
||||
component: 'ForecastingPage',
|
||||
title: 'Pronósticos',
|
||||
icon: 'forecasting',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
{
|
||||
path: '/app/analytics/sales',
|
||||
name: 'SalesAnalytics',
|
||||
component: 'SalesAnalyticsPage',
|
||||
title: 'Análisis de Ventas',
|
||||
icon: 'sales',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
{
|
||||
path: '/app/analytics/ai-insights',
|
||||
name: 'AIInsights',
|
||||
component: 'AIInsightsPage',
|
||||
title: 'Insights de IA',
|
||||
icon: 'forecasting',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
{
|
||||
path: '/app/analytics/performance',
|
||||
name: 'PerformanceAnalytics',
|
||||
component: 'PerformanceAnalyticsPage',
|
||||
title: 'Análisis de Rendimiento',
|
||||
icon: 'sales',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
},
|
||||
|
||||
// Communications Section
|
||||
{
|
||||
path: '/app/communications',
|
||||
name: 'Communications',
|
||||
component: 'CommunicationsPage',
|
||||
title: 'Comunicaciones',
|
||||
icon: 'notifications',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
children: [
|
||||
{
|
||||
path: '/app/communications/alerts',
|
||||
name: 'Alerts',
|
||||
component: 'AlertsPage',
|
||||
title: 'Alertas',
|
||||
icon: 'notifications',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/communications/notifications',
|
||||
name: 'Notifications',
|
||||
component: 'NotificationsPage',
|
||||
title: 'Notificaciones',
|
||||
icon: 'notifications',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/communications/preferences',
|
||||
name: 'Preferences',
|
||||
component: 'PreferencesPage',
|
||||
title: 'Preferencias',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// 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,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Onboarding Section
|
||||
{
|
||||
path: '/app/onboarding',
|
||||
name: 'Onboarding',
|
||||
component: 'OnboardingPage',
|
||||
title: 'Configuración Inicial',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
children: [
|
||||
{
|
||||
path: '/app/onboarding/setup',
|
||||
name: 'OnboardingSetup',
|
||||
component: 'OnboardingSetupPage',
|
||||
title: 'Configuración Básica',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/onboarding/upload',
|
||||
name: 'OnboardingUpload',
|
||||
component: 'OnboardingUploadPage',
|
||||
title: 'Carga de Datos',
|
||||
icon: 'data',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/onboarding/analysis',
|
||||
name: 'OnboardingAnalysis',
|
||||
component: 'OnboardingAnalysisPage',
|
||||
title: 'Análisis de Datos',
|
||||
icon: 'forecasting',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
{
|
||||
path: '/app/onboarding/review',
|
||||
name: 'OnboardingReview',
|
||||
component: 'OnboardingReviewPage',
|
||||
title: 'Revisión Final',
|
||||
icon: 'settings',
|
||||
requiresAuth: true,
|
||||
showInNavigation: true,
|
||||
showInBreadcrumbs: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
// 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;
|
||||
};
|
||||
Reference in New Issue
Block a user