diff --git a/src/features/admin/pages/UsersPage.client.js b/src/features/admin/pages/UsersPage.client.js
index 58338b2..c5b2eaf 100644
--- a/src/features/admin/pages/UsersPage.client.js
+++ b/src/features/admin/pages/UsersPage.client.js
@@ -12,7 +12,6 @@ const UsersPageClient = ({ currentUserId }) => {
const toast = useToast();
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
- const [roleColorMap, setRoleColorMap] = useState({});
const [editingUserId, setEditingUserId] = useState(null);
const [pagination, setPagination] = useState({
@@ -48,12 +47,23 @@ const UsersPageClient = ({ currentUserId }) => {
key: 'role',
label: 'Rôle',
sortable: true,
- render: (user) => (
-
- {user.role}
-
- ),
- skeleton: { height: 'h-6', width: '80px', className: 'rounded-full' },
+ render: (user) => {
+ const roles = user.roles || [];
+ const visible = roles.slice(0, 3);
+ const overflow = roles.length - 3;
+ return (
+
+ {visible.map(role => (
+
+ {role.name}
+
+ ))}
+ {overflow > 0 && +{overflow}}
+ {roles.length === 0 && —}
+
+ );
+ },
+ skeleton: { height: 'h-6', width: '140px', className: 'rounded-full' },
},
{
key: 'email_verified',
@@ -116,19 +126,6 @@ const UsersPageClient = ({ currentUserId }) => {
}
};
- useEffect(() => {
- fetch('/zen/api/roles', { credentials: 'include' })
- .then(r => r.json())
- .then(data => {
- const map = {};
- for (const role of data.roles || []) {
- if (role.color) map[role.name.toLowerCase()] = role.color;
- }
- setRoleColorMap(map);
- })
- .catch(() => {});
- }, []);
-
useEffect(() => {
fetchUsers();
}, [sortBy, sortOrder, pagination.page, pagination.limit]);
diff --git a/src/features/auth/api.js b/src/features/auth/api.js
index 3203dd2..d0cadc3 100644
--- a/src/features/auth/api.js
+++ b/src/features/auth/api.js
@@ -129,7 +129,15 @@ async function handleListUsers(request) {
const quotedSortColumn = `"${sortColumn}"`;
const result = await query(
- `SELECT id, email, name, role, image, email_verified, created_at FROM zen_auth_users ORDER BY ${quotedSortColumn} ${order} LIMIT $1 OFFSET $2`,
+ `SELECT u.id, u.email, u.name, u.role, u.image, u.email_verified, u.created_at,
+ COALESCE(
+ (SELECT json_agg(json_build_object('id', r.id, 'name', r.name, 'color', r.color) ORDER BY r.created_at ASC)
+ FROM zen_auth_roles r
+ JOIN zen_auth_user_roles ur ON ur.role_id = r.id
+ WHERE ur.user_id = u.id),
+ '[]'::json
+ ) AS roles
+ FROM zen_auth_users u ORDER BY u.${quotedSortColumn} ${order} LIMIT $1 OFFSET $2`,
[limit, offset]
);