Documentation Index Fetch the complete documentation index at: https://mintlify.com/EdgarJr30/proyecto-de-grado-cms/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The application uses React Router v6 with a centralized route registry defined in src/Routes/appRoutes.tsx. All routes are lazy-loaded for optimal performance.
Route Definition
Routes are defined using a strongly-typed AppRoute interface:
export type AppRoute = {
path : string ; // URL path
element : JSX . Element ; // Lazy-loaded component
allowPerms : string []; // Required permissions
name ?: string ; // Display name
icon ?: JSX . Element ; // Sidebar icon
showInSidebar ?: boolean ; // Sidebar visibility
};
Route Registry
All application routes are defined in the APP_ROUTES array:
Example Routes
Public Routes
export const APP_ROUTES : AppRoute [] = [
{
path: '/inicio' ,
element: < DashboardPage />,
allowPerms: [ 'home:read' ],
name: 'Inicio' ,
icon: IconHome ,
showInSidebar: true ,
},
{
path: '/ordenes_trabajo' ,
element: < WorkOrdersPage />,
allowPerms: [
'work_orders:read' ,
'work_orders:full_access' ,
'work_orders:cancel' ,
'work_orders:delete' ,
],
name: 'Órdenes de Trabajo' ,
icon: IconWorkOrders ,
showInSidebar: true ,
},
{
path: '/tickets/:ticketId' ,
element: < TicketDetailsPage />,
allowPerms: [
'home:read' ,
'work_orders:read' ,
'work_orders:read_own' ,
'work_orders:full_access' ,
],
showInSidebar: false ,
},
];
export const PUBLIC_ROUTES = [
{ path: '/login' , element: < LoginPage /> },
{ path: '/403' , element: < ForbiddenPage /> },
{ path: '/' , element: < Navigate to = "/inicio" replace /> },
];
Lazy Loading
All page components are lazy-loaded to reduce initial bundle size:
import { lazy } from 'react' ;
const CreateTicketPage = lazy (() => import ( '../pages/CreateTicketPage' ));
const WorkOrdersPage = lazy (() => import ( '../pages/WorkOrdersPage' ));
const InventoryHomePage = lazy (() => import ( '../pages/inventory/InventoryHomePage' ));
// ...
Lazy loading reduces the initial JavaScript bundle by loading page components only when they are accessed.
Access Control
Route access is controlled through a layered permission system:
ProtectedRoute Wrapper
Checks if the user is authenticated: < ProtectedRoute >
< RequirePerm allowPerms = { route . allowPerms } >
< Suspense fallback = { < ScreenLoader /> } >
{ route . element }
</ Suspense >
</ RequirePerm >
</ ProtectedRoute >
RequirePerm Component
Validates user permissions against allowPerms: // User must have at least ONE permission from allowPerms array
< RequirePerm allowPerms = { [ 'work_orders:read' , 'work_orders:full_access' ] } >
< WorkOrdersPage />
</ RequirePerm >
Permission Check Logic
Uses the PermissionsContext to check user permissions: const { has } = usePermissions ();
const canAccess = allowPerms . some ( perm => has ( perm ));
Permission Array Behavior
The allowPerms array uses OR logic: users need at least one of the listed permissions to access the route.
// User needs EITHER work_orders:read OR work_orders:full_access
allowPerms : [ 'work_orders:read' , 'work_orders:full_access' ]
// User needs ONLY home:read
allowPerms : [ 'home:read' ]
Navigation Patterns
Programmatic Navigation
import { useNavigate } from 'react-router-dom' ;
function MyComponent () {
const navigate = useNavigate ();
const handleClick = () => {
navigate ( '/ordenes_trabajo' );
};
return < button onClick = { handleClick } > Go to Work Orders </ button > ;
}
Link Components
import { Link } from 'react-router-dom' ;
< Link to = "/tickets/123" > View Ticket </ Link >
Dynamic Routes
import { useParams } from 'react-router-dom' ;
function TicketDetailsPage () {
const { ticketId } = useParams <{ ticketId : string }>();
// Use ticketId to fetch ticket data
}
Routes with showInSidebar: true appear in the application sidebar:
Route Configuration
Hidden Route
{
path : '/inventario' ,
element : < InventoryHomePage />,
allowPerms : [ 'inventory:read' ],
name : 'Inventario' ,
icon : IconInventory ,
showInSidebar : true , // Shows in sidebar
}
Route Redirects
Legacy routes redirect to new locations:
{
path : '/admin/assets' ,
element : < Navigate to = "/inventory/assets" replace />,
allowPerms : [ 'assets:read' ],
showInSidebar : false ,
}
Inventory Subroutes
The inventory module has nested routes:
/inventario # Inventory home
├── /inventory/uoms # Units of measure
├── /inventory/parts # Parts catalog
├── /inventory/warehouses # Warehouses
│ └── /inventory/warehouses/:id/bins # Warehouse bins
├── /inventory/availability # Stock overview
├── /inventory/assets # Assets
├── /inventory/docs # Documents
│ ├── /inventory/docs/crear # Create document
│ └── /inventory/docs/:docId # Document editor
├── /inventory/vendors # Vendors
├── /inventory/reorder # Reorder policies
└── /inventory/kardex # Movement history
Admin Routes
Administration routes require elevated permissions:
{
path : '/admin/settings' ,
element : < AdminSettingsHubPage />,
allowPerms : [
'rbac:manage_roles' ,
'rbac:manage_permissions' ,
'society:read' ,
'special_incidents:read' ,
'assets:read' ,
],
name : 'Configuración' ,
icon : IconPermissions ,
showInSidebar : true ,
}
Error Routes
403 Forbidden Shown when user lacks permissions: { path : '/403' , element : < ForbiddenPage /> }
Root Redirect Root path redirects to dashboard: { path : '/' , element : < Navigate to = "/inicio" replace /> }
Route Icons
Icons are inline SVG elements:
const IconHome = (
< svg
xmlns = "http://www.w3.org/2000/svg"
fill = "none"
viewBox = "0 0 24 24"
strokeWidth = "1.5"
stroke = "currentColor"
className = "w-5 h-5 mr-2"
>
< path
strokeLinecap = "round"
strokeLinejoin = "round"
d = "m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12..."
/>
</ svg >
);
Always check that new routes have appropriate allowPerms values aligned with backend RLS policies.
Best Practices
Always use lazy loading for page components
Lazy loading keeps the initial bundle small and improves performance: const MyPage = lazy (() => import ( '../pages/MyPage' ));
Define permissions in allowPerms array
Never rely solely on UI-level permission checks. Backend RLS policies are the source of truth: allowPerms : [ 'feature:read' , 'feature:full_access' ]
Use showInSidebar strategically
Next Steps
Services Learn about the service layer
Components Explore UI components