import { useState, useEffect } from 'react'; import { Shield, Plus, Edit2, Trash2, Users } from 'lucide-react'; import { rolesApi, Role } from '../lib/rolesApi'; import RoleModal from '../components/roles/RoleModal'; import { PageHeader, EmptyState, ActionButton, CardSkeleton } from '../components/ui/LinearPrimitives'; export default function RolesPage() { const [roles, setRoles] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedRole, setSelectedRole] = useState(undefined); useEffect(() => { loadRoles(); }, []); const loadRoles = async () => { setLoading(true); try { const data = await rolesApi.getAll(); setRoles(data); } catch (e) { console.error(e); } finally { setLoading(false); } }; const handleEdit = (role: Role) => { setSelectedRole(role); setIsModalOpen(true); }; const handleCreate = () => { setSelectedRole(undefined); setIsModalOpen(true); }; const handleDelete = async (role: Role) => { if (role.isSystem) { alert('Cannot delete system roles.'); return; } if (!confirm(`Delete role "${role.name}"?`)) return; try { await rolesApi.delete(role.id); loadRoles(); } catch (e) { console.error(e); alert('Failed to delete role'); } }; return (
New Role } /> {loading ? (
{Array.from({ length: 4 }).map((_, i) => )}
) : roles.length === 0 ? ( Create Role } /> ) : (
{roles.map(role => (

{role.name} {role.isSystem && ( System )}

{role.description || 'No description'}

Access

{Object.keys(role.permissions).slice(0, 4).map(res => ( {res} ))} {Object.keys(role.permissions).length > 4 && ( +{Object.keys(role.permissions).length - 4} )} {Object.keys(role.permissions).length === 0 && ( No permissions )}
{role._count?.users || 0}
handleEdit(role)} variant="accent" /> {!role.isSystem && ( handleDelete(role)} variant="destructive" /> )}
))}
)} setIsModalOpen(false)} onSuccess={loadRoles} role={selectedRole} />
); }