admin/src/pages/roles/role-detail/RoleDetailPage.tsx

177 lines
8.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;