Gerencia rango operativo (crear citas), permisos por prefijo para rutas de detalle, matriz alineada (inventario para recepcion)
This commit is contained in:
@@ -14,7 +14,7 @@ const ROLE_RANK: Record<FrontendRole, number> = {
|
|||||||
cosmetologia: 50,
|
cosmetologia: 50,
|
||||||
psicologa: 50,
|
psicologa: 50,
|
||||||
farmacia: 50,
|
farmacia: 50,
|
||||||
gerencia: 10,
|
gerencia: 50,
|
||||||
marketing: 10,
|
marketing: 10,
|
||||||
lectura: 10,
|
lectura: 10,
|
||||||
};
|
};
|
||||||
@@ -155,13 +155,25 @@ export const AuthProvider: FC<{ children: ReactNode }> = ({ children }) => {
|
|||||||
|
|
||||||
const canSee = (href: string): boolean => {
|
const canSee = (href: string): boolean => {
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
|
// Resolución de permiso: primero href exacto (con query), luego por
|
||||||
|
// prefijo recortando el último segmento (/pacientes/PAT-123 -> /pacientes).
|
||||||
|
// '/' no matchea subrutas: solo aterriza por canSee('/'). Rutas que no
|
||||||
|
// matchean nada = visibles para todos.
|
||||||
|
const segments = href.split('?')[0].split('/').filter(Boolean);
|
||||||
|
const candidates = [href, ...segments.map((_, i) => '/' + segments.slice(0, segments.length - i).join('/'))].filter((c) => c !== '/' || href === '/');
|
||||||
// Permisos personalizados: lista no vacía manda sobre la matriz por rol
|
// Permisos personalizados: lista no vacía manda sobre la matriz por rol
|
||||||
if (user.allowed_menus && user.allowed_menus.length > 0) {
|
if (user.allowed_menus && user.allowed_menus.length > 0) {
|
||||||
return user.allowed_menus.includes(href);
|
for (const cand of candidates) {
|
||||||
|
if (user.allowed_menus.includes(cand)) return true;
|
||||||
}
|
}
|
||||||
const allowed = (menuRoles || MENU_ROLES)[href];
|
return false;
|
||||||
if (!allowed) return true;
|
}
|
||||||
return allowed.includes(user.role);
|
const matrix = menuRoles || MENU_ROLES;
|
||||||
|
for (const cand of candidates) {
|
||||||
|
const allowed = matrix[cand];
|
||||||
|
if (allowed) return allowed.includes(user.role);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ export const MENU_ITEMS: { label: string; href: string }[] = [
|
|||||||
{ label: 'Recomendaciones', href: '/reportes?tab=recomendaciones' },
|
{ label: 'Recomendaciones', href: '/reportes?tab=recomendaciones' },
|
||||||
{ label: 'Exportar', href: '/reportes?tab=exportar' },
|
{ label: 'Exportar', href: '/reportes?tab=exportar' },
|
||||||
{ label: 'Cumpleañeros', href: '/cumpleanos' },
|
{ label: 'Cumpleañeros', href: '/cumpleanos' },
|
||||||
|
{ label: 'Mis ventas', href: '/mis-ventas' },
|
||||||
|
{ label: 'Chat', href: '/chat' },
|
||||||
{ label: 'Configuración', href: '/configuracion' },
|
{ label: 'Configuración', href: '/configuracion' },
|
||||||
{ label: 'Mensajes WACRM', href: '/wacrm/messages' },
|
{ label: 'Mensajes WACRM', href: '/wacrm/messages' },
|
||||||
{ label: 'Leads WACRM', href: '/wacrm/leads' },
|
{ label: 'Leads WACRM', href: '/wacrm/leads' },
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ ROLE_RANKS = {
|
|||||||
'cosmetologia': 50,
|
'cosmetologia': 50,
|
||||||
'psicologa': 50,
|
'psicologa': 50,
|
||||||
'farmacia': 50,
|
'farmacia': 50,
|
||||||
'gerencia': 10,
|
'gerencia': 50,
|
||||||
'marketing': 10,
|
'marketing': 10,
|
||||||
'lectura': 10,
|
'lectura': 10,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user