Imporve the role based forntend protected roles

This commit is contained in:
Urtzi Alfaro
2025-09-09 07:32:59 +02:00
parent ddb75f8e55
commit 5269a083b6
15 changed files with 286 additions and 91 deletions

View File

@@ -36,7 +36,7 @@ export const LoginForm: React.FC<LoginFormProps> = ({
const { login } = useAuthActions();
const isLoading = useAuthLoading();
const error = useAuthError();
const { showToast } = useToast();
const { success, error: showError } = useToast();
// Auto-focus on email field when component mounts
useEffect(() => {
@@ -76,17 +76,13 @@ export const LoginForm: React.FC<LoginFormProps> = ({
try {
await login(credentials.email, credentials.password);
showToast({
type: 'success',
title: 'Sesión iniciada correctamente',
message: '¡Bienvenido de vuelta a tu panadería!'
success('¡Bienvenido de vuelta a tu panadería!', {
title: 'Sesión iniciada correctamente'
});
onSuccess?.();
} catch (err) {
showToast({
type: 'error',
title: 'Error al iniciar sesión',
message: error || 'Email o contraseña incorrectos. Verifica tus credenciales.'
showError(error || 'Email o contraseña incorrectos. Verifica tus credenciales.', {
title: 'Error al iniciar sesión'
});
}
};

View File

@@ -2,6 +2,7 @@ import React, { useState, useCallback, forwardRef, useMemo } from 'react';
import { clsx } from 'clsx';
import { useLocation, useNavigate } from 'react-router-dom';
import { useAuthUser, useIsAuthenticated } from '../../../stores';
import { useCurrentTenantAccess } from '../../../stores/tenant.store';
import { getNavigationRoutes, canAccessRoute, ROUTES } from '../../../router/routes.config';
import { Button } from '../../ui';
import { Badge } from '../../ui';
@@ -127,6 +128,7 @@ export const Sidebar = forwardRef<SidebarRef, SidebarProps>(({
const navigate = useNavigate();
const user = useAuthUser();
const isAuthenticated = useIsAuthenticated();
const currentTenantAccess = useCurrentTenantAccess();
const [expandedItems, setExpandedItems] = useState<Set<string>>(new Set());
const [hoveredItem, setHoveredItem] = useState<string | null>(null);
@@ -160,8 +162,12 @@ export const Sidebar = forwardRef<SidebarRef, SidebarProps>(({
...item, // Create a shallow copy to avoid mutation
children: item.children ? filterItemsByPermissions(item.children) : item.children
})).filter(item => {
const userRoles = user.role ? [user.role] : [];
const userPermissions: string[] = user?.permissions || [];
// Combine global and tenant roles for comprehensive access control
const globalUserRoles = user.role ? [user.role as string] : [];
const tenantRole = currentTenantAccess?.role;
const tenantRoles = tenantRole ? [tenantRole as string] : [];
const allUserRoles = [...globalUserRoles, ...tenantRoles];
const tenantPermissions = currentTenantAccess?.permissions || [];
const hasAccess = !item.requiredPermissions && !item.requiredRoles ||
canAccessRoute(
@@ -171,8 +177,8 @@ export const Sidebar = forwardRef<SidebarRef, SidebarProps>(({
requiredPermissions: item.requiredPermissions
} as any,
isAuthenticated,
userRoles,
userPermissions
allUserRoles,
tenantPermissions
);
return hasAccess;
@@ -180,7 +186,7 @@ export const Sidebar = forwardRef<SidebarRef, SidebarProps>(({
};
return filterItemsByPermissions(navigationItems);
}, [navigationItems, isAuthenticated, user]);
}, [navigationItems, isAuthenticated, user, currentTenantAccess]);
// Handle item click
const handleItemClick = useCallback((item: NavigationItem) => {