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:
parent
91c2333fb9
commit
4a0507c09c
|
|
@ -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;
|
||||
Loading…
Reference in New Issue