admin/src/pages/Users.tsx

189 lines
8.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

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 { useState } from 'react';
import { Plus, Search, Filter, Users as UsersIcon, UserCheck, UserX } from 'lucide-react';
import { Table } from '../components/ui/Table';
import { Button } from '../components/ui/Button';
import { Modal } from '../components/ui/Modal';
import { Pagination } from '../components/ui/Pagination';
import { UserForm } from '../components/forms/UserForm';
import { PermissionWrapper } from '../components/common/PermissionWrapper';
import { TableColumn } from '../types';
import { UserFormData } from '../utils/validationSchemas';
import { PageContainer, PageTitle, StatValue } from '../components/ui/Typography';
const allUsers = [
{ id: 1, name: 'علی احمدی', email: 'ali@example.com', role: 'کاربر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۱۵', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 2, name: 'فاطمه حسینی', email: 'fateme@example.com', role: 'مدیر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۱۴', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 3, name: 'محمد رضایی', email: 'mohammad@example.com', role: 'کاربر', status: 'غیرفعال', createdAt: '۱۴۰۲/۰۸/۱۳', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 4, name: 'زهرا کریمی', email: 'zahra@example.com', role: 'کاربر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۱۲', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 5, name: 'حسن نوری', email: 'hassan@example.com', role: 'مدیر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۱۱', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 6, name: 'مریم صادقی', email: 'maryam@example.com', role: 'کاربر', status: 'غیرفعال', createdAt: '۱۴۰۲/۰۸/۱۰', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 7, name: 'احمد قاسمی', email: 'ahmad@example.com', role: 'کاربر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۰۹', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 8, name: 'سارا محمدی', email: 'sara@example.com', role: 'مدیر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۰۸', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 9, name: 'رضا کریمی', email: 'reza@example.com', role: 'کاربر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۰۷', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 10, name: 'نرگس احمدی', email: 'narges@example.com', role: 'کاربر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۰۶', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 11, name: 'امیر حسینی', email: 'amir@example.com', role: 'مدیر', status: 'فعال', createdAt: '۱۴۰۲/۰۸/۰۵', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
{ id: 12, name: 'مینا رضایی', email: 'mina@example.com', role: 'کاربر', status: 'غیرفعال', createdAt: '۱۴۰۲/۰۸/۰۴', phone: '۰۹۱۲۳۴۵۶۷۸۹' },
];
export const Users = () => {
const [searchTerm, setSearchTerm] = useState('');
const [showUserModal, setShowUserModal] = useState(false);
const [editingUser, setEditingUser] = useState<any>(null);
const [currentPage, setCurrentPage] = useState(1);
const itemsPerPage = 5;
const columns: TableColumn[] = [
{ key: 'name', label: 'نام', sortable: true },
{ key: 'email', label: 'ایمیل', sortable: true },
{ key: 'phone', label: 'تلفن' },
{ key: 'role', label: 'نقش' },
{
key: 'status',
label: 'وضعیت',
render: (value) => (
<span className={`px-2 py-1 rounded-full text-xs font-medium ${value === 'فعال'
? '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'
}`}>
{value}
</span>
)
},
{ key: 'createdAt', label: 'تاریخ عضویت', sortable: true },
{
key: 'actions',
label: 'عملیات',
render: (_, row) => (
<div className="flex space-x-2">
<Button
size="sm"
variant="secondary"
onClick={() => handleEditUser(row)}
>
ویرایش
</Button>
<PermissionWrapper permission={22}>
<Button
size="sm"
variant="danger"
onClick={() => handleDeleteUser(row.id)}
>
حذف
</Button>
</PermissionWrapper>
</div>
)
}
];
const filteredUsers = allUsers.filter((user: any) =>
user.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.email.toLowerCase().includes(searchTerm.toLowerCase())
);
const totalPages = Math.ceil(filteredUsers.length / itemsPerPage);
const startIndex = (currentPage - 1) * itemsPerPage;
const paginatedUsers = filteredUsers.slice(startIndex, startIndex + itemsPerPage);
const handleAddUser = () => {
setEditingUser(null);
setShowUserModal(true);
};
const handleEditUser = (user: any) => {
setEditingUser(user);
setShowUserModal(true);
};
const handleDeleteUser = (userId: number) => {
if (confirm('آیا از حذف این کاربر اطمینان دارید؟')) {
console.log('Deleting user:', userId);
}
};
const handleSubmitUser = (data: UserFormData) => {
console.log('User data:', data);
setShowUserModal(false);
};
const handleCloseModal = () => {
setShowUserModal(false);
setEditingUser(null);
};
return (
<PageContainer>
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
<div>
<PageTitle>مدیریت کاربران</PageTitle>
<p className="text-gray-600 dark:text-gray-400 mt-1">
{filteredUsers.length} کاربر یافت شد
</p>
</div>
<div className="flex items-center space-x-3 space-x-reverse">
<Button variant="secondary">
<Filter className="h-4 w-4 ml-2" />
فیلتر
</Button>
<PermissionWrapper permission={25}>
<button
onClick={handleAddUser}
className="flex items-center justify-center w-12 h-12 bg-primary-600 hover:bg-primary-700 rounded-full transition-colors duration-200 text-white shadow-lg hover:shadow-xl"
title="افزودن کاربر"
>
<Plus className="h-5 w-5" />
</button>
</PermissionWrapper>
</div>
</div>
<div className="card p-6">
<div className="mb-6">
<div className="relative">
<div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
<Search className="h-5 w-5 text-gray-400" />
</div>
<input
type="text"
placeholder="جستجو در کاربران..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="input pr-10 max-w-md"
/>
</div>
</div>
<div className="bg-white dark:bg-gray-800 rounded-lg overflow-hidden">
<Table
columns={columns}
data={paginatedUsers}
loading={false}
/>
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={setCurrentPage}
itemsPerPage={itemsPerPage}
totalItems={filteredUsers.length}
/>
</div>
</div>
<Modal
title={editingUser ? "ویرایش کاربر" : "افزودن کاربر"}
isOpen={showUserModal}
onClose={handleCloseModal}
size="lg"
>
<UserForm
initialData={editingUser}
onSubmit={handleSubmitUser}
onCancel={handleCloseModal}
loading={false}
isEdit={!!editingUser}
/>
</Modal>
</PageContainer>
);
};