Imporve the routes and the menu

This commit is contained in:
Urtzi Alfaro
2025-09-19 12:06:26 +02:00
parent 105410c9d3
commit caf6d92850
5 changed files with 437 additions and 334 deletions

View File

@@ -76,10 +76,9 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
priority_level: PriorityLevel.NORMAL priority_level: PriorityLevel.NORMAL
}); });
// Product selection // Simple product selection
const [showProductModal, setShowProductModal] = useState(false); const [selectedProductId, setSelectedProductId] = useState('');
const [productSearch, setProductSearch] = useState(''); const [selectedQuantity, setSelectedQuantity] = useState(1);
const [selectedCategory, setSelectedCategory] = useState<string>('');
// API hooks // API hooks
const { data: customers = [] } = useCustomers({ const { data: customers = [] } = useCustomers({
@@ -110,8 +109,8 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
// Reset form when modal closes // Reset form when modal closes
setSelectedCustomer(null); setSelectedCustomer(null);
setOrderItems([]); setOrderItems([]);
setProductSearch(''); setSelectedProductId('');
setSelectedCategory(''); setSelectedQuantity(1);
setOrderData({ setOrderData({
order_type: OrderType.STANDARD, order_type: OrderType.STANDARD,
priority: PriorityLevel.NORMAL, priority: PriorityLevel.NORMAL,
@@ -125,13 +124,18 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
} }
}, [isOpen]); }, [isOpen]);
const handleAddProduct = (product: any) => { const handleAddSelectedProduct = () => {
const existingItem = orderItems.find(item => item.product_id === product.id); if (!selectedProductId || selectedQuantity <= 0) return;
const product = finishedProducts.find(p => p.id === selectedProductId);
if (!product) return;
const existingItem = orderItems.find(item => item.product_id === selectedProductId);
if (existingItem) { if (existingItem) {
setOrderItems(items => items.map(item => setOrderItems(items => items.map(item =>
item.product_id === product.id item.product_id === selectedProductId
? { ...item, quantity: item.quantity + 1 } ? { ...item, quantity: item.quantity + selectedQuantity }
: item : item
)); ));
} else { } else {
@@ -140,14 +144,17 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
product_name: product.name, product_name: product.name,
product_sku: product.sku || undefined, product_sku: product.sku || undefined,
product_category: product.category || undefined, product_category: product.category || undefined,
quantity: 1, quantity: selectedQuantity,
unit_of_measure: product.unit_of_measure || 'unidad', unit_of_measure: product.unit_of_measure || 'unidad',
unit_price: product.average_cost || product.standard_cost || 0, unit_price: product.average_cost || product.standard_cost || 0,
line_discount: 0 line_discount: 0
}; };
setOrderItems(items => [...items, newItem]); setOrderItems(items => [...items, newItem]);
} }
setShowProductModal(false);
// Reset selection
setSelectedProductId('');
setSelectedQuantity(1);
}; };
const handleUpdateItemQuantity = (productId: string, quantity: number) => { const handleUpdateItemQuantity = (productId: string, quantity: number) => {
@@ -213,22 +220,6 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
onClose(); onClose();
}; };
// Get unique categories for filtering
const uniqueCategories = Array.from(new Set(
finishedProducts
.map(product => product.category)
.filter(Boolean)
)).sort();
const filteredProducts = finishedProducts.filter(product => {
const matchesSearch = product.name.toLowerCase().includes(productSearch.toLowerCase()) ||
(product.category && product.category.toLowerCase().includes(productSearch.toLowerCase())) ||
(product.description && product.description.toLowerCase().includes(productSearch.toLowerCase()));
const matchesCategory = !selectedCategory || product.category === selectedCategory;
return matchesSearch && matchesCategory;
});
// Convert form data to StatusModal sections // Convert form data to StatusModal sections
const modalSections: StatusModalSection[] = [ const modalSections: StatusModalSection[] = [
@@ -238,8 +229,30 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
fields: [ fields: [
{ {
label: 'Cliente Seleccionado', label: 'Cliente Seleccionado',
value: selectedCustomer ? `${selectedCustomer.name} (${selectedCustomer.customer_code})` : 'Ninguno', value: selectedCustomer ? selectedCustomer.id : '',
span: 2 type: 'select',
editable: true,
placeholder: 'Seleccionar cliente...',
options: customers.map(customer => ({
value: customer.id,
label: `${customer.name} (${customer.customer_code})`
})),
span: 1
},
{
label: 'Nuevo Cliente',
value: (
<Button
variant="outline"
size="sm"
onClick={() => setShowCustomerForm(true)}
className="w-full"
>
<Plus className="w-4 h-4 mr-2" />
Agregar Cliente
</Button>
),
span: 1
} }
] ]
}, },
@@ -281,15 +294,88 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
icon: Package, icon: Package,
fields: [ fields: [
{ {
label: 'Total de Productos', label: 'Agregar Producto',
value: orderItems.length, value: (
highlight: true <div className="flex gap-3 items-end">
}, <div className="flex-1">
{ <select
label: 'Lista de Productos', value={selectedProductId}
value: orderItems.length > 0 ? orderItems.map(item => `${item.product_name} (x${item.quantity})`).join(', ') : 'Sin productos', onChange={(e) => setSelectedProductId(e.target.value)}
className="w-full px-3 py-2 border border-[var(--border-secondary)] rounded-md focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-transparent bg-[var(--bg-primary)]"
>
<option value="">Seleccionar producto...</option>
{finishedProducts.map(product => (
<option key={product.id} value={product.id}>
{product.name} - {(product.average_cost || product.standard_cost || 0).toFixed(2)}
</option>
))}
</select>
</div>
<div className="w-24">
<Input
type="number"
min="1"
value={selectedQuantity}
onChange={(e) => setSelectedQuantity(Number(e.target.value))}
placeholder="Cant."
/>
</div>
<Button
onClick={handleAddSelectedProduct}
disabled={!selectedProductId || selectedQuantity <= 0}
className="whitespace-nowrap"
>
<Plus className="w-4 h-4 mr-1" />
Agregar
</Button>
</div>
),
span: 2 span: 2
} },
...(orderItems.length > 0 ? [{
label: 'Productos en el Pedido',
value: (
<div className="space-y-2">
{orderItems.map((item, index) => (
<div key={`${item.product_id}-${index}`} className="flex items-center justify-between p-3 bg-[var(--bg-secondary)] rounded-lg">
<div className="flex-1">
<h4 className="font-medium text-[var(--text-primary)]">{item.product_name}</h4>
<p className="text-sm text-[var(--text-secondary)]">
{item.unit_price.toFixed(2)} × {item.quantity} = {(item.unit_price * item.quantity).toFixed(2)}
</p>
</div>
<div className="flex items-center gap-2">
<Button
size="sm"
variant="outline"
onClick={() => handleUpdateItemQuantity(item.product_id, item.quantity - 1)}
disabled={item.quantity <= 1}
>
<Minus className="w-4 h-4" />
</Button>
<span className="min-w-[2rem] text-center font-medium">{item.quantity}</span>
<Button
size="sm"
variant="outline"
onClick={() => handleUpdateItemQuantity(item.product_id, item.quantity + 1)}
>
<Plus className="w-4 h-4" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() => handleUpdateItemQuantity(item.product_id, 0)}
className="text-red-600 hover:text-red-700 ml-2"
>
<X className="w-4 h-4" />
</Button>
</div>
</div>
))}
</div>
),
span: 2
}] : [])
] ]
}, },
{ {
@@ -334,7 +420,12 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
const field = section.fields[fieldIndex]; const field = section.fields[fieldIndex];
// Update order data based on field changes // Update order data based on field changes
if (section.title === 'Detalles del Pedido') { if (section.title === 'Cliente') {
if (field.label === 'Cliente Seleccionado') {
const customer = customers.find(c => c.id === value);
setSelectedCustomer(customer || null);
}
} else if (section.title === 'Detalles del Pedido') {
if (field.label === 'Tipo de Pedido') { if (field.label === 'Tipo de Pedido') {
setOrderData(prev => ({ ...prev, order_type: value as OrderType })); setOrderData(prev => ({ ...prev, order_type: value as OrderType }));
} else if (field.label === 'Prioridad') { } else if (field.label === 'Prioridad') {
@@ -361,17 +452,6 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
size="2xl" size="2xl"
showDefaultActions={false} showDefaultActions={false}
actions={[ actions={[
{
label: selectedCustomer ? 'Cambiar Cliente' : 'Seleccionar Cliente',
variant: 'outline',
onClick: () => setShowCustomerSelector(true)
},
{
label: 'Agregar Productos',
variant: 'outline',
onClick: () => setShowProductModal(true),
icon: Plus
},
{ {
label: 'Cancelar', label: 'Cancelar',
variant: 'outline', variant: 'outline',
@@ -392,118 +472,6 @@ export const OrderFormModal: React.FC<OrderFormModalProps> = ({
</div> </div>
{/* Product Selection Modal - Using StatusModal for consistency */}
<StatusModal
isOpen={showProductModal}
onClose={() => setShowProductModal(false)}
mode="view"
title="Seleccionar Productos"
subtitle="Elija productos terminados para agregar al pedido"
size="2xl"
showDefaultActions={false}
sections={[
{
title: 'Filtros',
icon: Package,
fields: [
{
label: 'Buscar productos',
value: productSearch,
type: 'text',
editable: true,
placeholder: 'Buscar productos...',
span: 1
},
{
label: 'Categoría',
value: selectedCategory,
type: 'select',
editable: true,
placeholder: 'Todas las categorías',
options: [
{ value: '', label: 'Todas las categorías' },
...uniqueCategories.map(category => ({
value: category,
label: category
}))
],
span: 1
}
]
},
{
title: 'Productos Disponibles',
icon: ShoppingCart,
fields: [
{
label: 'Lista de productos',
value: (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 max-h-96 overflow-y-auto">
{productsLoading ? (
<div className="col-span-2 text-center py-8">
<p className="text-[var(--text-secondary)]">Cargando productos...</p>
</div>
) : filteredProducts.length === 0 ? (
<div className="col-span-2 text-center py-8">
<p className="text-[var(--text-secondary)]">
{productSearch ? 'No se encontraron productos que coincidan con la búsqueda' : 'No hay productos finalizados disponibles'}
</p>
</div>
) : (
filteredProducts.map(product => (
<div key={product.id} className="border border-[var(--border-primary)] rounded-lg p-4 hover:bg-[var(--bg-secondary)]">
<div className="flex items-start justify-between">
<div className="flex-1">
<h4 className="font-medium text-[var(--text-primary)]">{product.name}</h4>
{product.description && (
<p className="text-sm text-[var(--text-secondary)] mt-1">{product.description}</p>
)}
<div className="flex items-center mt-2 flex-wrap gap-2">
{product.category && (
<Badge variant="soft" color="gray">
{product.category}
</Badge>
)}
<span className="text-lg font-semibold text-[var(--color-info)]">
{(product.average_cost || product.standard_cost || 0).toFixed(2)}
</span>
</div>
</div>
<Button
size="sm"
onClick={() => handleAddProduct(product)}
disabled={!product.is_active || (product.total_quantity || 0) <= 0}
>
<Plus className="w-4 h-4 mr-1" />
Agregar
</Button>
</div>
<div className="text-xs text-[var(--text-tertiary)] mt-2 flex justify-between">
<span>Stock: {product.total_quantity || 0} {product.unit_of_measure}</span>
{product.sku && <span>SKU: {product.sku}</span>}
</div>
</div>
))
)}
</div>
),
span: 2
}
]
}
]}
onFieldChange={(sectionIndex, fieldIndex, value) => {
if (sectionIndex === 0) {
if (fieldIndex === 0) {
setProductSearch(String(value));
} else if (fieldIndex === 1) {
setSelectedCategory(String(value));
}
}
}}
/>
{/* New Customer Modal - Using StatusModal for consistency */} {/* New Customer Modal - Using StatusModal for consistency */}
<StatusModal <StatusModal

View File

@@ -17,6 +17,7 @@ import {
Truck, Truck,
Zap, Zap,
Database, Database,
Store,
GraduationCap, GraduationCap,
Bell, Bell,
Settings, Settings,
@@ -93,6 +94,7 @@ const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
procurement: Truck, procurement: Truck,
pos: Zap, pos: Zap,
data: Database, data: Database,
database: Store,
training: GraduationCap, training: GraduationCap,
notifications: Bell, notifications: Bell,
settings: Settings, settings: Settings,

View File

@@ -0,0 +1,97 @@
import React from 'react';
import { Outlet, useLocation } from 'react-router-dom';
import { PageHeader } from '../../../components/layout/PageHeader/PageHeader';
import { Database, Package, ShoppingCart, Truck, Settings, Users, MessageSquare } from 'lucide-react';
const DatabasePage: React.FC = () => {
const location = useLocation();
const isParentRoute = location.pathname === '/app/database';
if (!isParentRoute) {
return <Outlet />;
}
return (
<div className="p-6 space-y-6">
<PageHeader
title="Mi Panadería"
description="Consulta y gestiona toda la información de tu panadería"
/>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-blue-100 rounded-lg">
<Package className="w-6 h-6 text-blue-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Recetas</h3>
</div>
<p className="text-gray-600">Gestiona las recetas de tus productos</p>
</div>
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-green-100 rounded-lg">
<ShoppingCart className="w-6 h-6 text-green-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Pedidos</h3>
</div>
<p className="text-gray-600">Consulta el estado de todos los pedidos</p>
</div>
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-yellow-100 rounded-lg">
<Truck className="w-6 h-6 text-yellow-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Proveedores</h3>
</div>
<p className="text-gray-600">Gestiona tus proveedores</p>
</div>
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-red-100 rounded-lg">
<Database className="w-6 h-6 text-red-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Inventario</h3>
</div>
<p className="text-gray-600">Estado actual del inventario</p>
</div>
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-indigo-100 rounded-lg">
<Settings className="w-6 h-6 text-indigo-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Configuración de Panadería</h3>
</div>
<p className="text-gray-600">Configuración general de tu panadería</p>
</div>
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-orange-100 rounded-lg">
<Users className="w-6 h-6 text-orange-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Gestión de Equipo</h3>
</div>
<p className="text-gray-600">Administra tu equipo de trabajo</p>
</div>
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
<div className="flex items-center space-x-3 mb-4">
<div className="p-2 bg-teal-100 rounded-lg">
<MessageSquare className="w-6 h-6 text-teal-600" />
</div>
<h3 className="text-lg font-semibold text-gray-900">Preferencias de Comunicación</h3>
</div>
<p className="text-gray-600">Configura notificaciones y comunicaciones</p>
</div>
</div>
</div>
);
};
export default DatabasePage;

View File

@@ -33,6 +33,9 @@ const BakeryConfigPage = React.lazy(() => import('../pages/app/settings/bakery-c
const TeamPage = React.lazy(() => import('../pages/app/settings/team/TeamPage')); const TeamPage = React.lazy(() => import('../pages/app/settings/team/TeamPage'));
const SubscriptionPage = React.lazy(() => import('../pages/app/settings/subscription/SubscriptionPage')); const SubscriptionPage = React.lazy(() => import('../pages/app/settings/subscription/SubscriptionPage'));
// Database pages
const DatabasePage = React.lazy(() => import('../pages/app/database/DatabasePage'));
// Data pages // Data pages
const WeatherPage = React.lazy(() => import('../pages/app/data/weather/WeatherPage')); const WeatherPage = React.lazy(() => import('../pages/app/data/weather/WeatherPage'));
const TrafficPage = React.lazy(() => import('../pages/app/data/traffic/TrafficPage')); const TrafficPage = React.lazy(() => import('../pages/app/data/traffic/TrafficPage'));
@@ -72,76 +75,118 @@ export const AppRouter: React.FC = () => {
} }
/> />
{/* Operations Routes */} {/* Operations Routes - Business Operations Only */}
<Route <Route
path="/app/operations/inventory" path="/app/operations/procurement"
element={
<ProtectedRoute>
<AppShell>
<InventoryPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/operations/production"
element={
<ProtectedRoute>
<AppShell>
<ProductionPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/operations/recipes"
element={
<ProtectedRoute>
<AppShell>
<RecipesPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/operations/procurement"
element={ element={
<ProtectedRoute> <ProtectedRoute>
<AppShell> <AppShell>
<ProcurementPage /> <ProcurementPage />
</AppShell> </AppShell>
</ProtectedRoute> </ProtectedRoute>
} }
/> />
<Route <Route
path="/app/operations/suppliers" path="/app/operations/production"
element={ element={
<ProtectedRoute> <ProtectedRoute>
<AppShell> <AppShell>
<SuppliersPage /> <ProductionPage />
</AppShell> </AppShell>
</ProtectedRoute> </ProtectedRoute>
} }
/> />
<Route <Route
path="/app/operations/orders" path="/app/operations/pos"
element={
<ProtectedRoute>
<AppShell>
<OrdersPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/operations/pos"
element={ element={
<ProtectedRoute> <ProtectedRoute>
<AppShell> <AppShell>
<POSPage /> <POSPage />
</AppShell> </AppShell>
</ProtectedRoute> </ProtectedRoute>
} }
/>
{/* Database Routes - Current Bakery Status */}
<Route
path="/app/database"
element={
<ProtectedRoute>
<AppShell>
<DatabasePage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/recipes"
element={
<ProtectedRoute>
<AppShell>
<RecipesPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/orders"
element={
<ProtectedRoute>
<AppShell>
<OrdersPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/suppliers"
element={
<ProtectedRoute>
<AppShell>
<SuppliersPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/inventory"
element={
<ProtectedRoute>
<AppShell>
<InventoryPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/bakery-config"
element={
<ProtectedRoute>
<AppShell>
<BakeryConfigPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/team"
element={
<ProtectedRoute>
<AppShell>
<TeamPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/database/preferences"
element={
<ProtectedRoute>
<AppShell>
<PreferencesPage />
</AppShell>
</ProtectedRoute>
}
/> />
{/* Analytics Routes */} {/* Analytics Routes */}
@@ -187,18 +232,6 @@ export const AppRouter: React.FC = () => {
/> />
{/* Settings Routes */}
<Route
path="/app/settings/preferences"
element={
<ProtectedRoute>
<AppShell>
<PreferencesPage />
</AppShell>
</ProtectedRoute>
}
/>
{/* Settings Routes */} {/* Settings Routes */}
<Route <Route
path="/app/settings/profile" path="/app/settings/profile"
@@ -210,26 +243,6 @@ export const AppRouter: React.FC = () => {
</ProtectedRoute> </ProtectedRoute>
} }
/> />
<Route
path="/app/settings/bakery-config"
element={
<ProtectedRoute>
<AppShell>
<BakeryConfigPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route
path="/app/settings/team"
element={
<ProtectedRoute>
<AppShell>
<TeamPage />
</AppShell>
</ProtectedRoute>
}
/>
<Route <Route
path="/app/settings/subscription" path="/app/settings/subscription"
element={ element={

View File

@@ -44,14 +44,14 @@ export const ROUTES = {
DASHBOARD: '/app/dashboard', DASHBOARD: '/app/dashboard',
// Inventory Management // Inventory Management
INVENTORY: '/app/operations/inventory', INVENTORY: '/app/database/inventory',
INVENTORY_INGREDIENTS: '/inventory/ingredients', INVENTORY_INGREDIENTS: '/inventory/ingredients',
INVENTORY_STOCK: '/inventory/stock', INVENTORY_STOCK: '/inventory/stock',
INVENTORY_MOVEMENTS: '/inventory/movements', INVENTORY_MOVEMENTS: '/inventory/movements',
INVENTORY_ALERTS: '/inventory/alerts', INVENTORY_ALERTS: '/inventory/alerts',
INVENTORY_QUALITY: '/inventory/quality', INVENTORY_QUALITY: '/inventory/quality',
INVENTORY_REPORTS: '/inventory/reports', INVENTORY_REPORTS: '/inventory/reports',
// Production Management // Production Management
PRODUCTION: '/app/operations/production', PRODUCTION: '/app/operations/production',
PRODUCTION_BATCHES: '/production/batches', PRODUCTION_BATCHES: '/production/batches',
@@ -75,33 +75,41 @@ export const ROUTES = {
FORECASTING_ANALYTICS: '/forecasting/analytics', FORECASTING_ANALYTICS: '/forecasting/analytics',
// Orders Management // Orders Management
ORDERS: '/orders', ORDERS: '/app/database/orders',
ORDERS_LIST: '/orders/list', ORDERS_LIST: '/orders/list',
ORDERS_QUEUE: '/orders/queue', ORDERS_QUEUE: '/orders/queue',
ORDERS_HISTORY: '/orders/history', ORDERS_HISTORY: '/orders/history',
ORDERS_CUSTOMERS: '/orders/customers', ORDERS_CUSTOMERS: '/orders/customers',
// Procurement // Procurement
PROCUREMENT: '/procurement', PROCUREMENT: '/app/operations/procurement',
PROCUREMENT_ORDERS: '/procurement/orders', PROCUREMENT_ORDERS: '/procurement/orders',
PROCUREMENT_SUPPLIERS: '/procurement/suppliers', PROCUREMENT_SUPPLIERS: '/procurement/suppliers',
PROCUREMENT_DELIVERIES: '/procurement/deliveries', PROCUREMENT_DELIVERIES: '/procurement/deliveries',
PROCUREMENT_ANALYTICS: '/procurement/analytics', PROCUREMENT_ANALYTICS: '/procurement/analytics',
// Recipes
RECIPES: '/app/database/recipes',
// Suppliers
SUPPLIERS: '/app/database/suppliers',
// Point of Sale // Point of Sale
POS: '/pos', POS: '/app/operations/pos',
POS_INTEGRATION: '/pos/integration', POS_INTEGRATION: '/pos/integration',
POS_TRANSACTIONS: '/pos/transactions', POS_TRANSACTIONS: '/pos/transactions',
POS_WEBHOOKS: '/pos/webhooks', POS_WEBHOOKS: '/pos/webhooks',
POS_SETTINGS: '/pos/settings', POS_SETTINGS: '/pos/settings',
// Data Management // Data Management
DATA: '/data', DATA: '/app/data',
DATA_IMPORT: '/data/import', DATA_IMPORT: '/data/import',
DATA_EXPORT: '/data/export', DATA_EXPORT: '/data/export',
DATA_EXTERNAL: '/data/external', DATA_EXTERNAL: '/data/external',
DATA_WEATHER: '/data/weather', DATA_WEATHER: '/app/data/weather',
DATA_EVENTS: '/data/events', DATA_EVENTS: '/app/data/events',
DATA_TRAFFIC: '/app/data/traffic',
// Training & ML // Training & ML
TRAINING: '/training', TRAINING: '/training',
@@ -118,14 +126,16 @@ export const ROUTES = {
// Settings // Settings
SETTINGS: '/settings', SETTINGS: '/settings',
SETTINGS_PROFILE: '/settings/profile', SETTINGS_PROFILE: '/app/settings/profile',
SETTINGS_TENANT: '/settings/tenant', SETTINGS_TENANT: '/settings/tenant',
SETTINGS_USERS: '/settings/users', SETTINGS_USERS: '/settings/users',
SETTINGS_PERMISSIONS: '/settings/permissions', SETTINGS_PERMISSIONS: '/settings/permissions',
SETTINGS_INTEGRATIONS: '/settings/integrations', SETTINGS_INTEGRATIONS: '/settings/integrations',
SETTINGS_PREFERENCES: '/settings/preferences', SETTINGS_PREFERENCES: '/app/database/preferences',
SETTINGS_BILLING: '/settings/billing', SETTINGS_BILLING: '/settings/billing',
SETTINGS_SUBSCRIPTION: '/app/settings/subscription', SETTINGS_SUBSCRIPTION: '/app/settings/subscription',
SETTINGS_BAKERY_CONFIG: '/app/database/bakery-config',
SETTINGS_TEAM: '/app/database/team',
// Reports // Reports
REPORTS: '/reports', REPORTS: '/reports',
@@ -207,7 +217,7 @@ export const routesConfig: RouteConfig[] = [
}, },
}, },
// Operations Section // Operations Section - Business Operations Only
{ {
path: '/app/operations', path: '/app/operations',
name: 'Operations', name: 'Operations',
@@ -217,46 +227,6 @@ export const routesConfig: RouteConfig[] = [
requiresAuth: true, requiresAuth: true,
showInNavigation: true, showInNavigation: true,
children: [ children: [
{
path: '/app/operations/production',
name: 'Production',
component: 'ProductionPage',
title: 'Producción',
icon: 'production',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/operations/orders',
name: 'Orders',
component: 'OrdersPage',
title: 'Pedidos',
icon: 'orders',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/operations/inventory',
name: 'Inventory',
component: 'InventoryPage',
title: 'Inventario',
icon: 'inventory',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/operations/recipes',
name: 'Recipes',
component: 'RecipesPage',
title: 'Recetas',
icon: 'production',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{ {
path: '/app/operations/procurement', path: '/app/operations/procurement',
name: 'Procurement', name: 'Procurement',
@@ -268,11 +238,11 @@ export const routesConfig: RouteConfig[] = [
showInBreadcrumbs: true, showInBreadcrumbs: true,
}, },
{ {
path: '/app/operations/suppliers', path: '/app/operations/production',
name: 'Suppliers', name: 'Production',
component: 'SuppliersPage', component: 'ProductionPage',
title: 'Proveedores', title: 'Producción',
icon: 'procurement', icon: 'production',
requiresAuth: true, requiresAuth: true,
showInNavigation: true, showInNavigation: true,
showInBreadcrumbs: true, showInBreadcrumbs: true,
@@ -290,6 +260,91 @@ export const routesConfig: RouteConfig[] = [
], ],
}, },
// 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',
name: 'Orders',
component: 'OrdersPage',
title: 'Pedidos',
icon: 'orders',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/database/suppliers',
name: 'Suppliers',
component: 'SuppliersPage',
title: 'Proveedores',
icon: 'procurement',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/database/inventory',
name: 'Inventory',
component: 'InventoryPage',
title: 'Inventario',
icon: 'inventory',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/database/bakery-config',
name: 'BakeryConfig',
component: 'BakeryConfigPage',
title: 'Configuración de Panadería',
icon: 'settings',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.ADMIN_ACCESS,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/database/team',
name: 'Team',
component: 'TeamPage',
title: 'Gestión de Equipo',
icon: 'user',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.ADMIN_ACCESS,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/database/preferences',
name: 'CommunicationPreferences',
component: 'PreferencesPage',
title: 'Preferencias de Comunicación',
icon: 'settings',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
],
},
// Analytics Section // Analytics Section
{ {
path: '/app/analytics', path: '/app/analytics',
@@ -368,28 +423,6 @@ export const routesConfig: RouteConfig[] = [
showInNavigation: true, showInNavigation: true,
showInBreadcrumbs: true, showInBreadcrumbs: true,
}, },
{
path: '/app/settings/bakery-config',
name: 'BakeryConfig',
component: 'BakeryConfigPage',
title: 'Configuración de Panadería',
icon: 'settings',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.ADMIN_ACCESS,
showInNavigation: true,
showInBreadcrumbs: true,
},
{
path: '/app/settings/team',
name: 'Team',
component: 'TeamPage',
title: 'Gestión de Equipo',
icon: 'settings',
requiresAuth: true,
requiredRoles: ROLE_COMBINATIONS.ADMIN_ACCESS,
showInNavigation: true,
showInBreadcrumbs: true,
},
{ {
path: '/app/settings/subscription', path: '/app/settings/subscription',
name: 'Subscription', name: 'Subscription',
@@ -401,16 +434,6 @@ export const routesConfig: RouteConfig[] = [
showInNavigation: true, showInNavigation: true,
showInBreadcrumbs: true, showInBreadcrumbs: true,
}, },
{
path: '/app/settings/preferences',
name: 'CommunicationPreferences',
component: 'PreferencesPage',
title: 'Preferencias de Comunicación',
icon: 'settings',
requiresAuth: true,
showInNavigation: true,
showInBreadcrumbs: true,
},
], ],
}, },