'use client'; import { useState, useEffect, useCallback } from 'react'; import { UsersRound, Edit, Users, Check, X, Plus } from 'lucide-react'; import { permissionGroupsAPI } from '@/lib/api/admin'; import type { PermissionGroup } from '@/lib/api/admin'; import Modal from '@/components/Modal'; import LoadingSpinner from '@/components/LoadingSpinner'; const MODULES = [ { id: 'contacts', name: 'إدارة جهات الاتصال', nameEn: 'Contact Management' }, { id: 'crm', name: 'إدارة علاقات العملاء', nameEn: 'CRM' }, { id: 'inventory', name: 'المخزون والأصول', nameEn: 'Inventory & Assets' }, { id: 'projects', name: 'المهام والمشاريع', nameEn: 'Tasks & Projects' }, { id: 'hr', name: 'الموارد البشرية', nameEn: 'HR Management' }, { id: 'marketing', name: 'التسويق', nameEn: 'Marketing' }, { id: 'admin', name: 'لوحة الإدارة', nameEn: 'Admin' }, ]; const ACTIONS = [ { id: 'read', name: 'عرض' }, { id: 'create', name: 'إنشاء' }, { id: 'update', name: 'تعديل' }, { id: 'delete', name: 'حذف' }, { id: 'export', name: 'تصدير' }, { id: 'approve', name: 'اعتماد' }, { id: 'merge', name: 'دمج' }, ]; function hasAction(perm: { actions?: unknown } | undefined, action: string): boolean { if (!perm?.actions) return false; const actions = Array.isArray(perm.actions) ? perm.actions : []; return actions.includes('*') || actions.includes('all') || actions.includes(action); } function buildPermissionsFromMatrix(matrix: Record>) { return MODULES.filter((m) => Object.values(matrix[m.id] || {}).some(Boolean)).map((m) => { const actions = ACTIONS.filter((a) => matrix[m.id]?.[a.id]).map((a) => a.id); return { module: m.id, resource: '*', actions: actions.length === ACTIONS.length ? ['*'] : actions, }; }); } function buildMatrixFromPermissions(permissions: { module: string; resource: string; actions: string[] }[]) { const matrix: Record> = {}; for (const m of MODULES) { matrix[m.id] = {}; const perm = permissions.find((p) => p.module === m.id && (p.resource === '*' || p.resource === m.id)); const hasAll = perm && (Array.isArray(perm.actions) ? perm.actions.includes('*') || perm.actions.includes('all') : false); for (const a of ACTIONS) { matrix[m.id][a.id] = hasAll || hasAction(perm, a.id); } } return matrix; } export default function PermissionGroupsPage() { const [groups, setGroups] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedId, setSelectedId] = useState(null); const [showEditModal, setShowEditModal] = useState(false); const [showCreateModal, setShowCreateModal] = useState(false); const [createForm, setCreateForm] = useState({ name: '', nameAr: '', description: '' }); type PermissionMatrix = Record>; const [permissionMatrix, setPermissionMatrix] = useState({}); const [saving, setSaving] = useState(false); const fetchGroups = useCallback(async () => { setLoading(true); setError(null); try { const list = await permissionGroupsAPI.getAll(); setGroups(list); if (selectedId && !list.find((g) => g.id === selectedId)) setSelectedId(null); } catch (err: unknown) { setError(err instanceof Error ? err.message : 'فشل تحميل المجموعات'); } finally { setLoading(false); } }, [selectedId]); useEffect(() => { fetchGroups(); }, [fetchGroups]); const currentGroup = groups.find((g) => g.id === selectedId); useEffect(() => { if (currentGroup) { setPermissionMatrix(buildMatrixFromPermissions(currentGroup.permissions || [])); } }, [currentGroup?.id, currentGroup?.permissions]); const handleCreate = async (e: React.FormEvent) => { e.preventDefault(); if (!createForm.name.trim()) { alert('الاسم مطلوب'); return; } setSaving(true); try { const group = await permissionGroupsAPI.create({ name: createForm.name.trim(), nameAr: createForm.nameAr.trim() || undefined, description: createForm.description.trim() || undefined, }); setShowCreateModal(false); setCreateForm({ name: '', nameAr: '', description: '' }); await fetchGroups(); setSelectedId(group.id); setShowEditModal(true); } catch (err: unknown) { alert(err instanceof Error ? err.message : 'فشل الإنشاء'); } finally { setSaving(false); } }; const handleSavePermissions = async () => { if (!selectedId) return; setSaving(true); try { const permissions = buildPermissionsFromMatrix(permissionMatrix); await permissionGroupsAPI.updatePermissions(selectedId, permissions); setShowEditModal(false); fetchGroups(); } catch (err: unknown) { alert(err instanceof Error ? err.message : 'فشل الحفظ'); } finally { setSaving(false); } }; const handleTogglePermission = (moduleId: string, actionId: string) => { setPermissionMatrix((prev) => ({ ...prev, [moduleId]: { ...(prev[moduleId] || {}), [actionId]: !prev[moduleId]?.[actionId], }, })); }; return (

مجموعات الصلاحيات

مجموعات اختيارية تضيف صلاحيات إضافية للمستخدمين بغض النظر عن وظائفهم

{loading ? (
) : error ? (
{error}
) : (

المجموعات ({groups.length})

{groups.map((g) => (
setSelectedId(g.id)} className={`p-4 rounded-xl border-2 cursor-pointer transition-all ${ selectedId === g.id ? 'border-blue-600 bg-blue-50' : 'border-gray-200 bg-white hover:border-blue-300' }`} >

{g.nameAr || g.name}

{g.name}

{g._count?.userRoles ?? 0} مستخدم
))}
{currentGroup ? (

{currentGroup.nameAr || currentGroup.name}

{currentGroup.name}

مصفوفة الصلاحيات

{ACTIONS.map((a) => ( ))} {MODULES.map((m) => ( {ACTIONS.map((a) => { const has = permissionMatrix[m.id]?.[a.id]; return ( ); })} ))}
الوحدة{a.name}

{m.name}

{m.nameEn}

{has ? : }
) : (

اختر مجموعة

أو أنشئ مجموعة جديدة لإضافة صلاحيات اختيارية للمستخدمين

)}
)} setShowCreateModal(false)} title="إضافة مجموعة صلاحيات" size="md">
setCreateForm((p) => ({ ...p, name: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 rounded-lg" placeholder="e.g. Campaign Approver" />
setCreateForm((p) => ({ ...p, nameAr: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 rounded-lg" />