feat(roles): add role detail page

- Complete role information display
- Statistics and metadata sections
- List of assigned permissions
- Quick access to edit and permissions management
- Responsive layout with proper Persian typography
This commit is contained in:
hosseintaromi 2025-07-18 14:03:01 +03:30
parent 4b4fe84cee
commit cdf0eb29f3
1 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,175 @@
import { useNavigate, useParams } from "react-router-dom";
import { useRole } from "../core/_hooks";
import { Button } from "@/components/ui/Button";
import { LoadingSpinner } from "@/components/ui/LoadingSpinner";
import { ArrowRight, Edit, Users, Calendar, FileText } from "lucide-react";
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;