177 lines
8.8 KiB
TypeScript
177 lines
8.8 KiB
TypeScript
import { useParams, useNavigate } from 'react-router-dom';
|
||
import { ArrowRight, Shield, Users, Key, Edit, Calendar, FileText } from 'lucide-react';
|
||
import { Button } from '../../../components/ui/Button';
|
||
import { LoadingSpinner } from '../../../components/ui/LoadingSpinner';
|
||
import { useRole } from '../core/_hooks';
|
||
import { PermissionWrapper } from '../../../components/common/PermissionWrapper';
|
||
import { PageContainer, PageTitle, SectionTitle, SectionSubtitle, BodyText } from '../../../components/ui/Typography';
|
||
|
||
const RoleDetailPage = () => {
|
||
const navigate = useNavigate();
|
||
const { id = "" } = useParams();
|
||
|
||
const { data: role, isLoading, error } = useRole(id);
|
||
|
||
if (isLoading) return <LoadingSpinner />;
|
||
if (error) return <div className="text-red-600">خطا در بارگذاری اطلاعات نقش</div>;
|
||
if (!role) return <div>نقش یافت نشد</div>;
|
||
|
||
return (
|
||
<div className="p-6">
|
||
<div className="mb-6">
|
||
<div className="flex items-center justify-between mb-4">
|
||
<div className="flex items-center gap-4">
|
||
<Button
|
||
variant="secondary"
|
||
onClick={() => navigate('/roles')}
|
||
className="flex items-center gap-2"
|
||
>
|
||
<ArrowRight className="h-4 w-4" />
|
||
بازگشت
|
||
</Button>
|
||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||
جزئیات نقش
|
||
</h1>
|
||
</div>
|
||
|
||
<div className="flex gap-3">
|
||
<Button
|
||
variant="primary"
|
||
onClick={() => navigate(`/roles/${id}/permissions`)}
|
||
className="flex items-center gap-2"
|
||
>
|
||
<Users className="h-4 w-4" />
|
||
مدیریت دسترسیها
|
||
</Button>
|
||
<Button
|
||
variant="secondary"
|
||
onClick={() => navigate(`/roles/${id}/edit`)}
|
||
className="flex items-center gap-2"
|
||
>
|
||
<Edit className="h-4 w-4" />
|
||
ویرایش
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||
{/* اطلاعات اصلی */}
|
||
<div className="lg:col-span-2">
|
||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
|
||
<h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-6">
|
||
اطلاعات نقش
|
||
</h2>
|
||
|
||
<div className="space-y-6">
|
||
<div>
|
||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
نام نقش
|
||
</label>
|
||
<div className="p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
||
<p className="text-gray-900 dark:text-gray-100 font-medium">
|
||
{role.title}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
توضیحات
|
||
</label>
|
||
<div className="p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
||
<p className="text-gray-900 dark:text-gray-100">
|
||
{role.description}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* اطلاعات جانبی */}
|
||
<div className="space-y-6">
|
||
{/* آمار */}
|
||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
|
||
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
||
آمار
|
||
</h3>
|
||
<div className="space-y-4">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<Users className="h-4 w-4 text-blue-500" />
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">
|
||
تعداد دسترسیها
|
||
</span>
|
||
</div>
|
||
<span className="font-semibold text-gray-900 dark:text-gray-100">
|
||
{role.permissions?.length || 0}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* اطلاعات زمانی */}
|
||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
|
||
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
||
اطلاعات زمانی
|
||
</h3>
|
||
<div className="space-y-4">
|
||
<div>
|
||
<div className="flex items-center gap-2 mb-1">
|
||
<Calendar className="h-4 w-4 text-green-500" />
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">
|
||
تاریخ ایجاد
|
||
</span>
|
||
</div>
|
||
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||
{new Date(role.created_at).toLocaleDateString('fa-IR')}
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<div className="flex items-center gap-2 mb-1">
|
||
<FileText className="h-4 w-4 text-orange-500" />
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">
|
||
آخرین بهروزرسانی
|
||
</span>
|
||
</div>
|
||
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||
{new Date(role.updated_at).toLocaleDateString('fa-IR')}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* لیست دسترسیها */}
|
||
{role.permissions && role.permissions.length > 0 && (
|
||
<div className="mt-6">
|
||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
|
||
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
||
دسترسیهای تخصیص یافته
|
||
</h3>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||
{role.permissions.map((permission) => (
|
||
<div
|
||
key={permission.id}
|
||
className="p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg"
|
||
>
|
||
<h4 className="font-medium text-blue-900 dark:text-blue-100 mb-1">
|
||
{permission.title}
|
||
</h4>
|
||
<p className="text-sm text-blue-700 dark:text-blue-300">
|
||
{permission.description}
|
||
</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default RoleDetailPage;
|