diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index c0b6c35..5854c5f 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -39,7 +39,9 @@ const RequireAuth: FC<{ children: ReactNode; href: string }> = ({ children, href
const { user, loading, canSee } = useAuth();
if (loading) return ;
if (!user) return ;
- if (!canSee(href)) return ;
+ // La ruta "/" se maneja en HomeRoute (calcula landing por rol) para evitar
+ // el bucle de redirecciones cuando el rol no tiene '/' en la matriz.
+ if (!canSee(href) && href !== '/') return ;
return <>{children}>;
};
@@ -50,11 +52,30 @@ const LoginRoute: FC = () => {
return ;
};
-// Pantalla inicial por rol: el médico aterriza directo en su Agenda
+// Pantalla inicial por rol: el médico aterriza directo en su Agenda.
+// Si el rol no tiene acceso al Dashboard (matriz por rol), aterriza en la
+// primera sección visible; si no tiene ninguna, muestra "Sin acceso" en
+// lugar de redirigir a "/" en bucle (pantalla en blanco).
+const LANDING_CANDIDATOS = [
+ '/agenda', '/mis-ventas', '/pacientes', '/pos', '/visitas', '/consultas',
+ '/expedientes', '/medicos', '/servicios', '/ventas', '/pagos', '/monedero',
+ '/inventario', '/cortes', '/reportes', '/cumpleanos', '/wacrm/messages',
+ '/wacrm/leads', '/configuracion',
+];
+
const HomeRoute: FC = () => {
- const { user } = useAuth();
+ const { user, canSee } = useAuth();
if (user?.role === 'medico') return ;
- return ;
+ if (canSee('/')) return ;
+ for (const href of LANDING_CANDIDATOS) {
+ if (canSee(href)) return ;
+ }
+ return (
+
+
Sin acceso a módulos
+
Tu usuario no tiene secciones habilitadas. Contacta al administrador.
+
+ );
};
const App: FC = () => {
diff --git a/frontend/src/lib/auth.tsx b/frontend/src/lib/auth.tsx
index 4940e50..dde65ab 100644
--- a/frontend/src/lib/auth.tsx
+++ b/frontend/src/lib/auth.tsx
@@ -23,7 +23,7 @@ const ROLE_RANK: Record = {
// 'gerencia' (gerencia de la clínica) ve toda la operación excepto
// /configuracion (solo admin del sistema), /mis-ventas, /cumpleanos y /wacrm/*.
const MENU_ROLES: Record = {
- '/': ['admin', 'recepcion', 'medico', 'lectura', 'gerencia'],
+ '/' : ['admin', 'medico', 'recepcion', 'enfermeria', 'cosmetologia', 'psicologa', 'farmacia', 'gerencia', 'marketing', 'lectura'],
'/agenda': ['admin', 'recepcion', 'medico', 'gerencia'],
'/mis-ventas': ['medico'],
'/pacientes': ['admin', 'recepcion', 'medico', 'lectura', 'gerencia'],
diff --git a/odoo-addons/skeen_whatsapp/controllers/frontend.py b/odoo-addons/skeen_whatsapp/controllers/frontend.py
index 24875af..84bfcd0 100644
--- a/odoo-addons/skeen_whatsapp/controllers/frontend.py
+++ b/odoo-addons/skeen_whatsapp/controllers/frontend.py
@@ -94,10 +94,9 @@ class SkeenFrontendController(http.Controller):
if not login or not password:
return json_response({'status': 'error', 'message': 'Usuario y contraseña son obligatorios'}, 400)
User = request.env['skeen.frontend.user'].sudo()
- # Login insensible a mayúsculas/minúsculas (la gente escribe "Andrea").
- # =ilike trata % y _ como comodines: se quitan para buscar literal.
- login_lookup = login.replace('%', '').replace('_', '')
- user = User.search([('login', '=ilike', login_lookup), ('active', '=', True)], limit=1)
+ # Login insensible a mayúsculas/minúsculas: los logins guardados
+ # están en minúsculas, se busca la forma exacta en minúsculas.
+ user = User.search([('login', '=', login.lower()), ('active', '=', True)], limit=1)
if not user or not user.check_password(password):
return json_response({'status': 'error', 'message': 'Credenciales inválidas'}, 401)
user.write({'last_login': fields.Datetime.now()})
@@ -134,7 +133,7 @@ class SkeenFrontendController(http.Controller):
def auth_users_create(self, **kw):
try:
data = _parse_json_body()
- login = (data.get('login') or '').strip()
+ login = (data.get('login') or '').strip().lower()
name = (data.get('name') or '').strip()
password = data.get('password') or ''
role = data.get('role') or 'recepcion'
diff --git a/odoo-addons/skeen_whatsapp/roles.py b/odoo-addons/skeen_whatsapp/roles.py
index 77c2819..e8e3005 100644
--- a/odoo-addons/skeen_whatsapp/roles.py
+++ b/odoo-addons/skeen_whatsapp/roles.py
@@ -47,7 +47,7 @@ MENU_ROLES_KEY = 'skeen.menu_roles'
# operación EXCEPTO /configuracion (solo admin del sistema), /mis-ventas,
# /cumpleanos y /wacrm/*.
DEFAULT_MENU_ROLES = {
- '/': ['admin', 'recepcion', 'medico', 'lectura', 'gerencia'],
+ '/' : ['admin', 'medico', 'recepcion', 'enfermeria', 'cosmetologia', 'psicologa', 'farmacia', 'gerencia', 'marketing', 'lectura'],
'/agenda': ['admin', 'recepcion', 'medico', 'gerencia'],
'/mis-ventas': ['medico'],
'/pacientes': ['admin', 'recepcion', 'medico', 'lectura', 'gerencia'],