add delete option to roles
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Shield, Edit, Users, Check, X } from 'lucide-react';
|
||||
import { Shield, Edit, Trash2, Users, Check, X, Loader2 } from 'lucide-react';
|
||||
import { positionsAPI } from '@/lib/api/admin';
|
||||
import type { PositionRole, PositionPermission } from '@/lib/api/admin';
|
||||
import Modal from '@/components/Modal';
|
||||
@@ -67,6 +67,9 @@ export default function RolesManagement() {
|
||||
const [showEditModal, setShowEditModal] = useState(false);
|
||||
const [permissionMatrix, setPermissionMatrix] = useState<Record<string, Record<string, boolean>>>({});
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
const [roleToDelete, setRoleToDelete] = useState<PositionRole | null>(null);
|
||||
|
||||
const fetchRoles = useCallback(async () => {
|
||||
setLoading(true);
|
||||
@@ -121,6 +124,36 @@ export default function RolesManagement() {
|
||||
}
|
||||
};
|
||||
|
||||
const openDeleteDialog = (role: PositionRole) => {
|
||||
setRoleToDelete(role);
|
||||
setShowDeleteDialog(true);
|
||||
};
|
||||
|
||||
const handleDeleteRole = async () => {
|
||||
if (!roleToDelete) return;
|
||||
setDeleting(true);
|
||||
try {
|
||||
await positionsAPI.delete(roleToDelete.id);
|
||||
|
||||
if (selectedRoleId === roleToDelete.id) {
|
||||
setSelectedRoleId(null);
|
||||
}
|
||||
|
||||
setShowDeleteDialog(false);
|
||||
setRoleToDelete(null);
|
||||
await fetchRoles();
|
||||
} catch (err: unknown) {
|
||||
const msg =
|
||||
(err as any)?.response?.data?.message ||
|
||||
(err as any)?.response?.data?.error ||
|
||||
(err as any)?.message ||
|
||||
'فشل حذف الدور';
|
||||
alert(msg);
|
||||
} finally {
|
||||
setDeleting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectRole = (id: string) => {
|
||||
setSelectedRoleId(id);
|
||||
setShowEditModal(false);
|
||||
@@ -177,16 +210,32 @@ export default function RolesManagement() {
|
||||
<Users className="h-4 w-4" />
|
||||
<span>{role.usersCount ?? role._count?.employees ?? 0} مستخدم</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedRoleId(role.id);
|
||||
setShowEditModal(true);
|
||||
}}
|
||||
className="p-1.5 text-blue-600 hover:bg-blue-50 rounded transition-colors"
|
||||
>
|
||||
<Edit className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
{/* Actions: Edit + Delete */}
|
||||
<div className="flex items-center gap-1">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedRoleId(role.id);
|
||||
setShowEditModal(true);
|
||||
}}
|
||||
className="p-1.5 text-blue-600 hover:bg-blue-50 rounded transition-colors"
|
||||
title="تعديل"
|
||||
>
|
||||
<Edit className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openDeleteDialog(role);
|
||||
}}
|
||||
className="p-1.5 text-red-600 hover:bg-red-50 rounded transition-colors"
|
||||
title="حذف"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@@ -269,6 +318,64 @@ export default function RolesManagement() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Delete Confirmation Dialog */}
|
||||
{showDeleteDialog && roleToDelete && (
|
||||
<div className="fixed inset-0 z-50 overflow-y-auto">
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-50"
|
||||
onClick={() => {
|
||||
if (!deleting) {
|
||||
setShowDeleteDialog(false);
|
||||
setRoleToDelete(null);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div className="flex min-h-screen items-center justify-center p-4">
|
||||
<div className="relative bg-white rounded-xl shadow-2xl p-6 max-w-md w-full">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="bg-red-100 p-3 rounded-full">
|
||||
<Trash2 className="h-6 w-6 text-red-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-gray-900">حذف الدور</h3>
|
||||
<p className="text-sm text-gray-600">هذا الإجراء لا يمكن التراجع عنه</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-gray-700 mb-6">
|
||||
هل أنت متأكد أنك تريد حذف دور{' '}
|
||||
<span className="font-semibold">{roleToDelete.titleAr || roleToDelete.title}</span>؟
|
||||
</p>
|
||||
<div className="flex items-center justify-end gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
setShowDeleteDialog(false);
|
||||
setRoleToDelete(null);
|
||||
}}
|
||||
className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors disabled:opacity-50"
|
||||
disabled={deleting}
|
||||
>
|
||||
إلغاء
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDeleteRole}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors disabled:opacity-50"
|
||||
disabled={deleting}
|
||||
>
|
||||
{deleting ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
جاري الحذف...
|
||||
</>
|
||||
) : (
|
||||
'حذف'
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Edit Permissions Modal */}
|
||||
<Modal
|
||||
isOpen={showEditModal}
|
||||
@@ -337,4 +444,4 @@ export default function RolesManagement() {
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,10 @@ export const positionsAPI = {
|
||||
return response.data.data || [];
|
||||
},
|
||||
|
||||
delete: async (positionId: string): Promise<void> => {
|
||||
await api.delete(`/admin/positions/${positionId}`);
|
||||
},
|
||||
|
||||
updatePermissions: async (
|
||||
positionId: string,
|
||||
permissions: Array<{ module: string; resource: string; actions: string[] }>
|
||||
@@ -263,4 +267,4 @@ export const healthAPI = {
|
||||
const response = await api.get('/admin/health').catch(() => ({ data: { data: {} } }));
|
||||
return response.data?.data || response.data || {};
|
||||
},
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user