Fase 3:
- Backend API: Autenticación y autorización básicas con JWT implementadas. Cambio de contraseña funcional. Módulo "Tipos de Pago" (CRUD completo) implementado en el backend (Controlador, Servicio, Repositorio) usando Dapper, transacciones y con lógica de historial. Se incluyen permisos en el token JWT. - Frontend React: Estructura base con Vite, TypeScript, MUI. Contexto de autenticación (AuthContext) que maneja el estado del usuario y el token. Página de Login. Modal de Cambio de Contraseña (forzado y opcional). Hook usePermissions para verificar permisos. Página GestionarTiposPagoPage con tabla, paginación, filtro, modal para crear/editar, y menú de acciones, respetando permisos. Layout principal (MainLayout) con navegación por Tabs (funcionalidad básica de navegación). Estructura de enrutamiento (AppRoutes) que maneja rutas públicas, protegidas y anidadas para módulos.
This commit is contained in:
		| @@ -1,63 +1,125 @@ | ||||
| import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; | ||||
| // src/routes/AppRoutes.tsx | ||||
| import React, { type JSX } from 'react'; | ||||
| import { BrowserRouter, Routes, Route, Navigate, Outlet } from 'react-router-dom'; | ||||
| import LoginPage from '../pages/LoginPage'; | ||||
| import HomePage from '../pages/HomePage'; // Crearemos esta página simple | ||||
| import HomePage from '../pages/HomePage'; | ||||
| import { useAuth } from '../contexts/AuthContext'; | ||||
| import ChangePasswordPage from '../pages/ChangePasswordPage'; // Crearemos esta | ||||
| import MainLayout from '../layouts/MainLayout'; // Crearemos este | ||||
| import MainLayout from '../layouts/MainLayout'; | ||||
| import { Typography } from '@mui/material'; | ||||
|  | ||||
| // Componente para proteger rutas | ||||
| // Distribución | ||||
| import DistribucionIndexPage from '../pages/Distribucion/DistribucionIndexPage'; | ||||
| import ESCanillasPage from '../pages/Distribucion/ESCanillasPage'; | ||||
| import ControlDevolucionesPage from '../pages/Distribucion/ControlDevolucionesPage'; | ||||
| import ESDistribuidoresPage from '../pages/Distribucion/ESDistribuidoresPage'; | ||||
| import SalidasOtrosDestinosPage from '../pages/Distribucion/SalidasOtrosDestinosPage'; | ||||
| import CanillasPage from '../pages/Distribucion/CanillasPage'; | ||||
| import DistribuidoresPage from '../pages/Distribucion/DistribuidoresPage'; | ||||
| import PublicacionesPage from '../pages/Distribucion/PublicacionesPage'; | ||||
| import OtrosDestinosPage from '../pages/Distribucion/OtrosDestinosPage'; | ||||
| import ZonasPage from '../pages/Distribucion/ZonasPage'; | ||||
| import EmpresasPage from '../pages/Distribucion/EmpresasPage'; | ||||
|  | ||||
| // Contables | ||||
| import ContablesIndexPage from '../pages/Contables/ContablesIndexPage'; | ||||
| import GestionarTiposPagoPage from '../pages/Contables/GestionarTiposPagoPage'; // Asumiendo que lo moviste aquí | ||||
|  | ||||
| // --- ProtectedRoute y PublicRoute SIN CAMBIOS --- | ||||
| const ProtectedRoute: React.FC<{ children: JSX.Element }> = ({ children }) => { | ||||
|     const { isAuthenticated, isLoading } = useAuth(); | ||||
|  | ||||
|     if (isLoading) { | ||||
|          // Muestra algo mientras verifica el token (ej: un spinner) | ||||
|          return <div>Cargando...</div>; | ||||
|     } | ||||
|  | ||||
|     return isAuthenticated ? children : <Navigate to="/login" replace />; | ||||
|   const { isAuthenticated, isLoading } = useAuth(); | ||||
|   // console.log("ProtectedRoute Check:", { path: window.location.pathname, isAuthenticated, isLoading }); | ||||
|   if (isLoading) return null; | ||||
|   if (!isAuthenticated) { | ||||
|     //    console.log("ProtectedRoute: Not authenticated, redirecting to /login"); | ||||
|        return <Navigate to="/login" replace />; | ||||
|   } | ||||
|   // console.log("ProtectedRoute: Authenticated, rendering children"); | ||||
|   return children; | ||||
| }; | ||||
|  | ||||
| // Componente para rutas públicas (redirige si ya está logueado) | ||||
| const PublicRoute: React.FC<{ children: JSX.Element }> = ({ children }) => { | ||||
|   const { isAuthenticated, isLoading } = useAuth(); | ||||
|  | ||||
|   if (isLoading) { | ||||
|        return <div>Cargando...</div>; | ||||
|   // console.log("PublicRoute Check:", { path: window.location.pathname, isAuthenticated, isLoading }); | ||||
|   if (isLoading) return null; | ||||
|   if (isAuthenticated) { | ||||
|     // console.log("PublicRoute: Authenticated, redirecting to /"); | ||||
|     return <Navigate to="/" replace />; | ||||
|   } | ||||
|  | ||||
|   return !isAuthenticated ? children : <Navigate to="/" replace />; | ||||
|   // console.log("PublicRoute: Not authenticated, rendering children"); | ||||
|   return children; | ||||
| }; | ||||
| // --- Fin Protected/Public --- | ||||
|  | ||||
| const MainLayoutWrapper: React.FC = () => ( | ||||
|   <MainLayout> | ||||
|       <Outlet /> | ||||
|   </MainLayout> | ||||
| ); | ||||
|  | ||||
| // Placeholder simple | ||||
| const PlaceholderPage: React.FC<{ moduleName: string }> = ({ moduleName }) => ( | ||||
|     <Typography variant="h5" sx={{ p:2 }}>Página Principal del Módulo: {moduleName}</Typography> | ||||
| ); | ||||
|  | ||||
| const AppRoutes = () => { | ||||
|   return ( | ||||
|     <BrowserRouter> | ||||
|       <Routes> | ||||
|         {/* Rutas Públicas */} | ||||
|         <Route path="/login" element={<PublicRoute><LoginPage /></PublicRoute>} /> | ||||
|         <Route path="/change-password" element={<ProtectedRoute><ChangePasswordPage /></ProtectedRoute>} /> {/* Asumimos que se accede logueado */} | ||||
| return ( | ||||
|   <BrowserRouter> | ||||
|     <Routes> {/* Un solo <Routes> de nivel superior */} | ||||
|       <Route path="/login" element={<PublicRoute><LoginPage /></PublicRoute>} /> | ||||
|  | ||||
|         {/* Rutas Protegidas dentro del Layout Principal */} | ||||
|         <Route | ||||
|           path="/*" // Captura todas las demás rutas | ||||
|           element={ | ||||
|             <ProtectedRoute> | ||||
|               <MainLayout> {/* Layout que tendrá la navegación principal */} | ||||
|                  {/* Aquí irán las rutas de los módulos */} | ||||
|                  <Routes> | ||||
|                       <Route index element={<HomePage />} /> {/* Página por defecto al loguearse */} | ||||
|                       {/* <Route path="/usuarios" element={<GestionUsuariosPage />} /> */} | ||||
|                       {/* <Route path="/zonas" element={<GestionZonasPage />} /> */} | ||||
|                       {/* ... otras rutas de módulos ... */} | ||||
|                       <Route path="*" element={<Navigate to="/" replace />} /> {/* Redirige rutas no encontradas al home */} | ||||
|                  </Routes> | ||||
|               </MainLayout> | ||||
|             </ProtectedRoute> | ||||
|           } | ||||
|         /> | ||||
|       </Routes> | ||||
|     </BrowserRouter> | ||||
|   ); | ||||
|       {/* Rutas Protegidas que usan el MainLayout */} | ||||
|       <Route | ||||
|         path="/" // La ruta padre para todas las secciones protegidas | ||||
|         element={ | ||||
|           <ProtectedRoute> | ||||
|              <MainLayoutWrapper/> | ||||
|           </ProtectedRoute> | ||||
|         } | ||||
|       > | ||||
|           {/* Rutas hijas que se renderizarán en el Outlet de MainLayoutWrapper */} | ||||
|           <Route index element={<HomePage />} /> {/* Para la ruta exacta "/" */} | ||||
|  | ||||
|           {/* Módulo de Distribución (anidado) */} | ||||
|           <Route path="distribucion" element={<DistribucionIndexPage />}> | ||||
|               <Route index element={<Navigate to="es-canillas" replace />} /> | ||||
|               <Route path="es-canillas" element={<ESCanillasPage />} /> | ||||
|               <Route path="control-devoluciones" element={<ControlDevolucionesPage />} /> | ||||
|               <Route path="es-distribuidores" element={<ESDistribuidoresPage />} /> | ||||
|               <Route path="salidas-otros-destinos" element={<SalidasOtrosDestinosPage />} /> | ||||
|               <Route path="canillas" element={<CanillasPage />} /> | ||||
|               <Route path="distribuidores" element={<DistribuidoresPage />} /> | ||||
|               <Route path="publicaciones" element={<PublicacionesPage />} /> | ||||
|               <Route path="otros-destinos" element={<OtrosDestinosPage />} /> | ||||
|               <Route path="zonas" element={<ZonasPage />} /> | ||||
|               <Route path="empresas" element={<EmpresasPage />} /> | ||||
|           </Route> | ||||
|  | ||||
|           {/* Módulo Contable (anidado) */} | ||||
|           <Route path="contables" element={<ContablesIndexPage />}> | ||||
|               <Route index element={<Navigate to="tipos-pago" replace />} /> | ||||
|               <Route path="tipos-pago" element={<GestionarTiposPagoPage />} /> | ||||
|               {/* Futuras sub-rutas de contables aquí */} | ||||
|           </Route> | ||||
|  | ||||
|           {/* Otros Módulos Principales (estos son "finales", no tienen más hijos) */} | ||||
|           <Route path="impresion" element={<PlaceholderPage moduleName="Impresión" />} /> | ||||
|           <Route path="reportes" element={<PlaceholderPage moduleName="Reportes" />} /> | ||||
|           <Route path="radios" element={<PlaceholderPage moduleName="Radios" />} /> | ||||
|           {/* <Route path="usuarios" element={<PlaceholderPage moduleName="Usuarios" />} /> */} | ||||
|  | ||||
|           {/* Ruta catch-all DENTRO del layout protegido */} | ||||
|           <Route path="*" element={<Navigate to="/" replace />} /> | ||||
|       </Route> {/* Cierre de la ruta padre "/" */} | ||||
|  | ||||
|       {/* Podrías tener un catch-all global aquí si una ruta no coincide EN ABSOLUTO, | ||||
|           pero el path="*" dentro de la ruta "/" ya debería manejar la mayoría de los casos | ||||
|           después de un login exitoso. | ||||
|           Si un usuario no autenticado intenta una ruta inválida, ProtectedRoute lo manda a /login. | ||||
|       */} | ||||
|       {/* <Route path="*" element={<Navigate to="/login" replace />} /> */} | ||||
|  | ||||
|     </Routes> | ||||
|   </BrowserRouter> | ||||
| ); | ||||
| }; | ||||
|  | ||||
| export default AppRoutes; | ||||
		Reference in New Issue
	
	Block a user