feat: add AdminUserDetailPage for detailed admin user view

- Implemented AdminUserDetailPage to display user information
- Added loading and error handling states
- Included user roles and permissions display
- Integrated date formatting and status badge components
This commit is contained in:
hosseintaromi 2025-07-29 09:51:46 +03:30
parent 91c2333fb9
commit 4a0507c09c
1 changed files with 202 additions and 0 deletions

View File

@ -0,0 +1,202 @@
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowRight, Shield, Users, Key, Edit, Calendar, FileText, User } from 'lucide-react';
import { Button } from '../../../components/ui/Button';
import { LoadingSpinner } from '../../../components/ui/LoadingSpinner';
import { useAdminUser } from '../core/_hooks';
import { PermissionWrapper } from '../../../components/common/PermissionWrapper';
import { PageContainer, PageTitle, SectionTitle, SectionSubtitle, BodyText } from '../../../components/ui/Typography';
const AdminUserDetailPage = () => {
const navigate = useNavigate();
const { id = "" } = useParams();
const { data: user, isLoading, error } = useAdminUser(id);
if (isLoading) return <LoadingSpinner />;
if (error) return <div className="text-red-600">خطا در بارگذاری اطلاعات کاربر</div>;
if (!user) return <div>کاربر یافت نشد</div>;
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString('fa-IR');
};
const getStatusBadge = (status: string) => {
const isActive = status === 'active';
return (
<span className={`px-3 py-1 rounded-full text-sm font-medium ${isActive
? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'
: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'
}`}>
{isActive ? 'فعال' : 'غیرفعال'}
</span>
);
};
return (
<PageContainer>
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-3">
<button
onClick={() => navigate('/admin-users')}
className="flex items-center justify-center w-10 h-10 rounded-lg bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 transition-colors"
>
<ArrowRight className="h-5 w-5" />
</button>
<div>
<PageTitle>جزئیات کاربر ادمین</PageTitle>
<p className="text-gray-600 dark:text-gray-400">نمایش اطلاعات کامل کاربر ادمین</p>
</div>
</div>
<div className="flex gap-3">
<PermissionWrapper permission={23}>
<Button
onClick={() => navigate(`/admin-users/${id}/edit`)}
className="flex items-center gap-2"
>
<Edit className="h-4 w-4" />
ویرایش
</Button>
</PermissionWrapper>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2 space-y-6">
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg p-6">
<SectionTitle className="flex items-center gap-2 mb-4">
<User className="h-5 w-5" />
اطلاعات اصلی
</SectionTitle>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
نام
</label>
<BodyText>{user.first_name || 'تعریف نشده'}</BodyText>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
نام خانوادگی
</label>
<BodyText>{user.last_name || 'تعریف نشده'}</BodyText>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
نام کاربری
</label>
<BodyText>{user.username}</BodyText>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
وضعیت
</label>
{getStatusBadge(user.status)}
</div>
</div>
</div>
{user.roles && user.roles.length > 0 && (
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg p-6">
<SectionTitle className="flex items-center gap-2 mb-4">
<Shield className="h-5 w-5" />
نقشها
</SectionTitle>
<div className="flex flex-wrap gap-2">
{user.roles.map((role: any) => (
<span
key={role.id}
className="px-3 py-1 bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 rounded-full text-sm font-medium"
>
{role.title}
</span>
))}
</div>
</div>
)}
{user.permissions && user.permissions.length > 0 && (
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg p-6">
<SectionTitle className="flex items-center gap-2 mb-4">
<Key className="h-5 w-5" />
دسترسیهای مستقیم
</SectionTitle>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
{user.permissions.map((permission: any) => (
<div
key={permission.id}
className="p-3 bg-gray-50 dark:bg-gray-700 rounded-lg"
>
<div className="font-medium text-gray-900 dark:text-gray-100">
{permission.title}
</div>
<div className="text-sm text-gray-600 dark:text-gray-400">
{permission.description}
</div>
</div>
))}
</div>
</div>
)}
</div>
<div className="space-y-6">
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg p-6">
<SectionTitle className="flex items-center gap-2 mb-4">
<Calendar className="h-5 w-5" />
اطلاعات زمانی
</SectionTitle>
<div className="space-y-4">
<div>
<SectionSubtitle className="text-sm text-gray-600 dark:text-gray-400 mb-1">
تاریخ ایجاد
</SectionSubtitle>
<BodyText>
{user.created_at ? formatDate(user.created_at) : 'تعریف نشده'}
</BodyText>
</div>
<div>
<SectionSubtitle className="text-sm text-gray-600 dark:text-gray-400 mb-1">
آخرین بروزرسانی
</SectionSubtitle>
<BodyText>
{user.updated_at ? formatDate(user.updated_at) : 'تعریف نشده'}
</BodyText>
</div>
</div>
</div>
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg p-6">
<SectionTitle className="flex items-center gap-2 mb-4">
<FileText className="h-5 w-5" />
آمار سریع
</SectionTitle>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600 dark:text-gray-400">تعداد نقشها</span>
<span className="font-medium text-gray-900 dark:text-gray-100">
{user.roles ? user.roles.length : 0}
</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600 dark:text-gray-400">تعداد دسترسیها</span>
<span className="font-medium text-gray-900 dark:text-gray-100">
{user.permissions ? user.permissions.length : 0}
</span>
</div>
</div>
</div>
</div>
</div>
</PageContainer>
);
};
export default AdminUserDetailPage;