diff --git a/src/features/admin/components/UserEditModal.client.js b/src/features/admin/components/UserEditModal.client.js
index 1ee67a2..c272496 100644
--- a/src/features/admin/components/UserEditModal.client.js
+++ b/src/features/admin/components/UserEditModal.client.js
@@ -1,7 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
-import { Input, TagInput, Modal } from '@zen/core/shared/components';
+import { Input, TagInput, Modal, RoleBadge } from '@zen/core/shared/components';
import { useToast } from '@zen/core/toast';
const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => {
@@ -225,6 +225,9 @@ const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => {
value={selectedRoleIds}
onChange={setSelectedRoleIds}
placeholder="Rechercher un rôle..."
+ renderTag={(opt, onRemove) => (
+
+ )}
/>
)}
diff --git a/src/features/admin/pages/UsersPage.client.js b/src/features/admin/pages/UsersPage.client.js
index c5b2eaf..f562959 100644
--- a/src/features/admin/pages/UsersPage.client.js
+++ b/src/features/admin/pages/UsersPage.client.js
@@ -2,7 +2,7 @@
import { registerPage } from '../registry.js';
import { useState, useEffect } from 'react';
-import { Card, Table, Badge, StatusBadge, Button, UserAvatar, RelativeDate } from '@zen/core/shared/components';
+import { Card, Table, Badge, StatusBadge, Button, UserAvatar, RelativeDate, RoleBadge } from '@zen/core/shared/components';
import { PencilEdit01Icon } from '@zen/core/shared/icons';
import { useToast } from '@zen/core/toast';
import AdminHeader from '../components/AdminHeader.js';
@@ -54,9 +54,7 @@ const UsersPageClient = ({ currentUserId }) => {
return (
{visible.map(role => (
-
- {role.name}
-
+
))}
{overflow > 0 &&
+{overflow}}
{roles.length === 0 &&
—}
diff --git a/src/shared/components/RoleBadge.js b/src/shared/components/RoleBadge.js
new file mode 100644
index 0000000..4fb70a7
--- /dev/null
+++ b/src/shared/components/RoleBadge.js
@@ -0,0 +1,45 @@
+'use client';
+
+const hexToRgb = (hex) => {
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result
+ ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) }
+ : null;
+};
+
+const RoleBadge = ({ name, color, onRemove }) => {
+ const rgb = color ? hexToRgb(color) : null;
+ const style = rgb
+ ? { backgroundColor: `rgba(${rgb.r},${rgb.g},${rgb.b},0.15)`, borderColor: `rgba(${rgb.r},${rgb.g},${rgb.b},0.4)`, color }
+ : {};
+ const fallback = !rgb
+ ? 'bg-neutral-100 dark:bg-neutral-700 border-neutral-200 dark:border-neutral-600 text-neutral-700 dark:text-neutral-300'
+ : '';
+
+ return (
+
+ {rgb && (
+
+ )}
+ {name}
+ {onRemove && (
+
+ )}
+
+ );
+};
+
+export default RoleBadge;
diff --git a/src/shared/components/TagInput.js b/src/shared/components/TagInput.js
index cdd6495..196e5d5 100644
--- a/src/shared/components/TagInput.js
+++ b/src/shared/components/TagInput.js
@@ -3,45 +3,19 @@
import { useState, useRef, useEffect } from 'react';
import { createPortal } from 'react-dom';
-const hexToRgb = (hex) => {
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
- return result
- ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) }
- : null;
-};
-
-const Pill = ({ option, onRemove }) => {
- const rgb = option.color ? hexToRgb(option.color) : null;
- const pillStyle = rgb
- ? { backgroundColor: `rgba(${rgb.r},${rgb.g},${rgb.b},0.15)`, borderColor: `rgba(${rgb.r},${rgb.g},${rgb.b},0.4)`, color: option.color }
- : {};
- const fallbackClass = !rgb
- ? 'bg-neutral-100 dark:bg-neutral-700 border-neutral-200 dark:border-neutral-600 text-neutral-700 dark:text-neutral-300'
- : '';
-
- return (
-
(
+
+ {option.label}
+
- );
-};
+ ×
+
+
+);
const TagInput = ({
options = [],
@@ -51,6 +25,7 @@ const TagInput = ({
description,
placeholder = 'Ajouter...',
error,
+ renderTag,
}) => {
const [inputValue, setInputValue] = useState('');
const [isOpen, setIsOpen] = useState(false);
@@ -129,7 +104,9 @@ const TagInput = ({
onClick={() => { inputRef.current?.focus(); setIsOpen(true); }}
>
{selectedOptions.map(opt => (
-
removeOption(opt.value)} />
+ renderTag
+ ? renderTag(opt, () => removeOption(opt.value))
+ : removeOption(opt.value)} />
))}