189 lines
8.8 KiB
TypeScript
189 lines
8.8 KiB
TypeScript
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>
|
||
);
|
||
};
|