feat: version 3.1.0 -- Acceso por modulo y por usuario
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { BrandingProvider } from '../context/branding-context.jsx';
|
||||
import { ContentDialogHost } from '../components/ContentDialog.jsx';
|
||||
import { ToastHost } from '../components/ToastHost.jsx';
|
||||
import { ErrorBoundary } from '../components/ErrorBoundary.jsx';
|
||||
import { ProtectedRoute } from './ProtectedRoute.jsx';
|
||||
import { ProtectedRoute, ModuleRoute } from './ProtectedRoute.jsx';
|
||||
import AppShell from './AppShell.jsx';
|
||||
import LoginPage from '../pages/Login/LoginPage.jsx';
|
||||
import RegisterPage from '../pages/Login/RegisterPage.jsx';
|
||||
@@ -37,13 +37,13 @@ const router = createBrowserRouter(createRoutesFromElements(
|
||||
<Route path="/aceptar-invitacion" element={<AcceptInvitePage />} />
|
||||
<Route path="/" element={<ProtectedRoute><AppShell /></ProtectedRoute>}>
|
||||
<Route index element={<DashboardPage />} />
|
||||
<Route path="proyectos" element={<ProyectosPage />} />
|
||||
<Route path="proyectos/:id" element={<ProyectoDetallePage />} />
|
||||
<Route path="tareas-recurrentes" element={<RecurringTasksPage />} />
|
||||
<Route path="notas" element={<NotasPage />} />
|
||||
<Route path="contrasenas" element={<ContrasenasPage />} />
|
||||
<Route path="equipos" element={<EquiposPage />} />
|
||||
<Route path="organizacion" element={<OrganizacionPage />} />
|
||||
<Route path="proyectos" element={<ModuleRoute module="projects"><ProyectosPage /></ModuleRoute>} />
|
||||
<Route path="proyectos/:id" element={<ModuleRoute module="projects"><ProyectoDetallePage /></ModuleRoute>} />
|
||||
<Route path="tareas-recurrentes" element={<ModuleRoute module="recurring_tasks"><RecurringTasksPage /></ModuleRoute>} />
|
||||
<Route path="notas" element={<ModuleRoute module="notes"><NotasPage /></ModuleRoute>} />
|
||||
<Route path="contrasenas" element={<ModuleRoute module="vault"><ContrasenasPage /></ModuleRoute>} />
|
||||
<Route path="equipos" element={<ModuleRoute module="devices"><EquiposPage /></ModuleRoute>} />
|
||||
<Route path="organizacion" element={<ModuleRoute module="organization"><OrganizacionPage /></ModuleRoute>} />
|
||||
<Route path="configuracion" element={<ConfiguracionPage />} />
|
||||
</Route>
|
||||
</>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Navigate, useLocation } from 'react-router-dom';
|
||||
import { useAuth } from '../context/auth-context.jsx';
|
||||
import { hasModule } from '../utils/modules.js';
|
||||
|
||||
export function ProtectedRoute({ children }) {
|
||||
const { user, ready } = useAuth();
|
||||
@@ -9,3 +10,10 @@ export function ProtectedRoute({ children }) {
|
||||
if (!user) return <Navigate to="/login" replace state={{ from: `${location.pathname}${location.search}` }} />;
|
||||
return children;
|
||||
}
|
||||
|
||||
// Modulo deshabilitado para el usuario: al Panel (el backend igual responde 403).
|
||||
export function ModuleRoute({ module, children }) {
|
||||
const { user } = useAuth();
|
||||
if (!hasModule(user, module)) return <Navigate to="/" replace />;
|
||||
return children;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user