'use client'; import { useState, useEffect } from 'react'; import { Input, Textarea, Switch, Modal, ColorPicker } from '@zen/core/shared/components'; import { useToast } from '@zen/core/toast'; const RoleEditModal = ({ roleId, isOpen, onClose, onSaved }) => { const toast = useToast(); const isNew = !roleId || roleId === 'new'; const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [isSystem, setIsSystem] = useState(false); const [name, setName] = useState(''); const [description, setDescription] = useState(''); const [color, setColor] = useState('#6b7280'); const [selectedPerms, setSelectedPerms] = useState([]); // Catalogue dynamique des permissions (core + modules), récupéré via l'API. const [permissionGroups, setPermissionGroups] = useState({}); useEffect(() => { if (!isOpen) return; fetchPermissions(); if (isNew) { setName(''); setDescription(''); setColor('#6b7280'); setSelectedPerms([]); setIsSystem(false); return; } fetchRole(); }, [isOpen, roleId]); const fetchPermissions = async () => { try { const response = await fetch('/zen/api/permissions', { credentials: 'include' }); if (!response.ok) return; const data = await response.json(); setPermissionGroups(data.groups || {}); } catch { // Si le catalogue n'est pas joignable, on laisse l'utilisateur sauvegarder // ses changements ; les permissions invalides sont filtrées côté serveur. } }; const fetchRole = async () => { try { setLoading(true); const response = await fetch(`/zen/api/roles/${roleId}`, { credentials: 'include' }); if (!response.ok) { toast.error('Rôle introuvable'); onClose(); return; } const data = await response.json(); const role = data.role; setName(role.name || ''); setDescription(role.description || ''); setColor(role.color || '#6b7280'); setSelectedPerms(role.permission_keys || []); setIsSystem(role.is_system || false); } catch { toast.error('Impossible de charger ce rôle'); onClose(); } finally { setLoading(false); } }; const togglePerm = (key) => { setSelectedPerms(prev => prev.includes(key) ? prev.filter(k => k !== key) : [...prev, key] ); }; const handleSubmit = async () => { if (!name.trim()) { toast.error('Le nom du rôle est requis'); return; } try { setSaving(true); const url = isNew ? '/zen/api/roles' : `/zen/api/roles/${roleId}`; const method = isNew ? 'POST' : 'PUT'; const response = await fetch(url, { method, credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name.trim(), description: description.trim() || null, color, permissionKeys: selectedPerms, }), }); const data = await response.json(); if (!response.ok) { toast.error(data.message || 'Impossible de sauvegarder ce rôle'); return; } toast.success(isNew ? 'Rôle créé' : 'Rôle mis à jour'); onSaved?.(); onClose(); } catch { toast.error('Impossible de sauvegarder ce rôle'); } finally { setSaving(false); } }; const title = isNew ? 'Nouveau rôle' : `Modifier "${name}"`; return ( {loading ? (
) : (