Overview
The User Management system provides administrative control over user accounts, allowing you to view, create, and delete users. Users are authenticated via JWT tokens and inherit permissions from their assigned roles.
User Interface
Users Page
The main users page (/users) displays all system users in a data grid:
// src/pages/Users/UsersPage.tsx:54-77
const columnDefs = useMemo (() => [
{ headerName: "ID" , field: "id" , width: 70 },
{ headerName: "Nombre" , field: "name" , flex: 1 },
{ headerName: "Apellidos" , field: "last_name" , flex: 1 },
{ headerName: "Email" , field: "email" , flex: 1 },
{
headerName: "Rol" ,
field: "roles" ,
flex: 1 ,
valueGetter : ( params : any ) => params . data . roles ?. map (( r : any ) => r . name ). join ( ', ' ) || ''
},
{
headerName: "Acciones" ,
field: "id" ,
width: 100 ,
cellRenderer : ( params : any ) => (
< Box >
< IconButton size = "small" color = "error" onClick = { () => handleDelete ( params . value ) } >
< DeleteIcon />
</ IconButton >
</ Box >
)
}
], []);
The users table is powered by AG Grid with built-in sorting, filtering, and pagination support.
User Data Structure
User Model
// src/store/authStore.ts:3-9
interface User {
id : number ;
name : string ;
last_name : string ;
email : string ;
[ key : string ] : any ;
}
User-Role Relationship
Users can have one or more roles assigned. Each role contains a set of permissions:
User
└─ Roles[] (one or many)
└─ Permissions[] (many)
└─ slug (string)
API Integration
User Endpoints
// src/services/admin.service.tsx:127-128
export const getUsers = async () => await axios . get ( ` ${ apiUrl } /users` );
export const deleteUser = async ( id : number ) => await axios . delete ( ` ${ apiUrl } /users/ ${ id } ` );
The current implementation only supports viewing and deleting users. User creation is typically handled through the employee creation flow or backend processes.
Loading Users
// src/pages/Users/UsersPage.tsx:21-28
const loadUsers = async () => {
try {
const res = await getUsers ();
setUsers ( res . data );
} catch ( error ) {
console . error ( error );
}
};
User Operations
Deleting Users
User deletion requires confirmation and provides feedback:
// src/pages/Users/UsersPage.tsx:30-52
const handleDelete = async ( id : number ) => {
const result = await Swal . fire ({
title: '¿Estás seguro?' ,
text: "No podrás revertir esta acción" ,
icon: 'warning' ,
showCancelButton: true ,
confirmButtonColor: '#3085d6' ,
cancelButtonColor: '#d33' ,
confirmButtonText: 'Sí, eliminar' ,
cancelButtonText: 'Cancelar'
});
if ( result . isConfirmed ) {
try {
await deleteUser ( id );
Swal . fire ( 'Eliminado' , 'El usuario ha sido eliminado.' , 'success' );
loadUsers ();
} catch ( error ) {
console . error ( error );
Swal . fire ( 'Error' , 'No se pudo eliminar el usuario' , 'error' );
}
}
};
Confirmation Dialog
User is prompted to confirm deletion with a warning message
API Request
If confirmed, DELETE request is sent to /users/{id}
UI Update
On success, the user list is refreshed and a success message is displayed
Authentication Flow
Login Process
When a user logs in, their information and permissions are loaded:
// src/auth/pages/LoginPage.tsx:32-37
const { data : userData } = await getInfoUser ();
const perms = userData . roles . flatMap (( role : any ) =>
role . permissions . map (( p : any ) => p . slug )
);
setAuth ( userData , perms );
JWT Token Storage
Authentication tokens are stored in localStorage and included in all API requests:
// src/services/admin.service.tsx:5-16
axios . interceptors . request . use (
( config : any ) => {
const token = localStorage . getItem ( "token" );
if ( token ) {
config . headers [ "Authorization" ] = "Bearer " + token ;
}
config . headers [ "Access-Control-Allow-Origin" ] = "*" ;
config . headers [ "Access-Control-Allow-Methods" ] = "GET, POST, PUT, DELETE" ;
config . headers [ "Access-Control-Allow-Headers" ] = "Content-Type, Authorization" ;
config . headers [ "Content-Type" ] = "application/json" ;
return config ;
}
);
Session Persistence
User sessions are restored on page reload:
// src/router/AppRouter.tsx:45-62
useEffect (() => {
const token = localStorage . getItem ( "token" );
if ( token && ! isAuthenticated ) {
getInfoUser ()
. then (( res ) => {
const user = res . data ;
const perms = user . roles . flatMap (( role : any ) =>
role . permissions . map (( p : any ) => p . slug )
);
setAuth ( user , perms );
})
. catch (( err ) => {
console . error ( "Error fetching user info in router:" , err );
});
}
}, [ isAuthenticated , setAuth ]);
Access Control
Required Permission
To access the Users page, users must have the users.view permission:
// src/core/MenuSidebar.tsx:84-92
{
id : 8 ,
title : "Administración" ,
text_menu : "Usuarios" ,
icon : < ManageAccountsIcon ></ ManageAccountsIcon > ,
path : "/users" ,
permission : "users.view" ,
page : < UsersPage ></ UsersPage >
}
Users without the users.view permission will not see the Users menu item and will be redirected if they attempt to access the route directly.
User Store
Auth State Management
The application uses Zustand for global auth state:
// src/store/authStore.ts:11-33
interface AuthState {
user : User | null ;
permissions : string [];
isAuthenticated : boolean ;
setAuth : ( user : User , permissions : string []) => void ;
clearAuth : () => void ;
}
export const useAuthStore = create < AuthState >(( set ) => ({
user: null ,
permissions: [],
isAuthenticated: false ,
setAuth : ( user , permissions ) => set ({
user ,
permissions ,
isAuthenticated: true
}),
clearAuth : () => set ({
user: null ,
permissions: [],
isAuthenticated: false
}),
}));
Accessing Current User
Components can access the current user data:
import { useAuthStore } from "../../store/authStore" ;
const { user , permissions } = useAuthStore ();
console . log ( user . name ); // Current user's name
console . log ( user . email ); // Current user's email
Error Handling
Response Interceptor
Global error handling for API responses:
// src/services/admin.service.tsx:24-34
axios . interceptors . response . use (
( res : any ) => {
return res ;
},
( err ) => {
const status = err . response ? err . response . status : 0 ;
const data = err . response ? err . response . data : null ;
Response ( status , data );
return Promise . reject ( err );
}
);
The Response utility function handles common HTTP status codes and displays appropriate error messages to users.
Best Practices
Security Always validate user permissions before performing sensitive operations
Data Validation Verify user data on both frontend and backend before processing
Audit Trail Consider logging user deletions and role changes for security audits
Token Management Implement token refresh mechanisms for long-running sessions
Integration with Employees
User accounts are typically created when employees are added to the system. See the Employees documentation for details on the employee-user relationship.
Each employee can have an associated user account for system access, inheriting permissions from their assigned roles.