import React, { useEffect, useMemo, useState } from 'react'; import DataTable from '../components/DataTable'; import { rolesAPI, listPermissions } from '../services/api'; import { Plus, Trash2, Search, Pencil } from 'lucide-react'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { getErrorMessage, getSuccessMessage } from '../utils/errorHandler'; const Roles = () => { const [roles, setRoles] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [name, setName] = useState(''); const [permissionsInput, setPermissionsInput] = useState(''); const [nameFilter, setNameFilter] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [editingRole, setEditingRole] = useState(null); const [selectedPermissions, setSelectedPermissions] = useState([]); const [permissionOptions, setPermissionOptions] = useState([]); const fetchRoles = async (q = '') => { try { setLoading(true); const list = await rolesAPI.list(q); setRoles(list); } catch (e) { const errorMsg = getErrorMessage(e); setError(errorMsg); toast.error(errorMsg); } finally { setLoading(false); } }; useEffect(() => { fetchRoles(); (async () => { try { const perms = await listPermissions(); setPermissionOptions(Array.isArray(perms) ? perms : []); } catch (_) { setPermissionOptions([]); } })(); }, []); const onAddRole = async (e) => { e.preventDefault(); if (!name.trim()) return; const perms = selectedPermissions.length > 0 ? selectedPermissions : permissionsInput.split(',').map(p => p.trim()).filter(Boolean); try { await rolesAPI.create({ name: name.trim(), permissions: perms }); setName(''); setPermissionsInput(''); setSelectedPermissions([]); await fetchRoles(nameFilter); setIsModalOpen(false); toast.success('Role created successfully'); } catch (err) { const errorMsg = getErrorMessage(err); setError(errorMsg); toast.error(errorMsg); } }; const onDelete = async (id) => { try { await rolesAPI.remove(id); await fetchRoles(nameFilter); toast.success('Role deleted successfully'); } catch (err) { toast.error(getErrorMessage(err)); } }; const openEdit = (role) => { setEditingRole(role); setName(role.name || ''); setSelectedPermissions(Array.isArray(role.permissions) ? role.permissions : []); setPermissionsInput(''); setIsEditModalOpen(true); }; const onUpdateRole = async (e) => { e.preventDefault(); if (!editingRole) return; const perms = selectedPermissions.length > 0 ? selectedPermissions : permissionsInput.split(',').map(p => p.trim()).filter(Boolean); try { await rolesAPI.update(editingRole.id, { name: name.trim(), permissions: perms }); await fetchRoles(nameFilter); setIsEditModalOpen(false); setEditingRole(null); setName(''); setPermissionsInput(''); setSelectedPermissions([]); toast.success('Role updated successfully'); } catch (err) { const errorMsg = getErrorMessage(err); setError(errorMsg); toast.error(errorMsg); } }; const columns = useMemo(() => [ { key: 'name', header: 'Name' }, { key: 'permissions', header: 'Permissions', render: (val) => Array.isArray(val) ? val.join(', ') : '' }, { key: 'userType', header: 'User Type' }, { key: 'actions', header: 'Actions', render: (_val, row) => (
Manage roles: add, filter by name, and delete
Create a new role with permissions
Update role name and permissions