diff --git a/src/web/src/components/layout/AppSidebar.tsx b/src/web/src/components/layout/AppSidebar.tsx
index 7c9330e..c858e9b 100644
--- a/src/web/src/components/layout/AppSidebar.tsx
+++ b/src/web/src/components/layout/AppSidebar.tsx
@@ -6,8 +6,10 @@ import {
Zap,
Settings,
UserPlus,
+ Users,
ShieldCheck,
KeyRound,
+ Lock,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
@@ -86,6 +88,25 @@ export function SidebarNav() {
)
})}
+ {/* Profile / account section — visible for all authenticated users */}
+
+
+ Mi cuenta
+
+
+
+
+ Cambiar contraseña
+
+
{/* Admin-only section */}
{isAdmin && (
<>
@@ -94,6 +115,18 @@ export function SidebarNav() {
Administración
+
+
+ Usuarios
+
{children}>
}
+/**
+ * Wraps a protected route with ProtectedLayout + MustChangePasswordGate.
+ * The gate forces users with mustChangePassword=true to /perfil/contrasena.
+ */
+function ProtectedPage({
+ children,
+ requiredPermissions,
+}: {
+ children: React.ReactNode
+ requiredPermissions?: string[]
+}) {
+ return (
+
+
+ {children}
+
+
+ )
+}
+
export function AppRoutes() {
return (
+ {/* Public routes */}
}
/>
+
+ {/* Change password — protected but NO MustChangePasswordGate (avoids redirect loop) */}
-
+
}
/>
+
+ {/* Protected routes — all wrapped with MustChangePasswordGate */}
+ }
+ />
+
+
+
+
+ }
+ />
+
-
-
-
-
+
+
+
}
/>
+
+
+
+
+ }
+ />
+
+
+
+
+ }
+ />
+
-
-
-
-
+
+
+
}
/>
+
-
-
-
-
+
+
+
}
/>
+
-
-
-
-
+
+
+
}
/>
+
-
-
-
-
+
+
}
/>
+
} />
)