refactor: simplify Topbar component and remove unused code

- Removed breadcrumb functionality and related code from Topbar.
- Consolidated mobile and desktop sidebar toggle logic.
- Adjusted icon sizes and styles for consistency.
- Cleaned up unused imports and props in Topbar.

refactor: enhance DoctorDetailPage session editor UI

- Improved layout and styling of session editor for better usability.
- Removed advanced settings toggle and integrated relevant fields directly.
- Added visual indicators for session slots and rest periods.

refactor: streamline DoctorsPage component

- Removed bulk selection functionality and related state management.
- Simplified rendering logic for doctor list and adjusted table structure.
- Cleaned up unused imports and components for better readability.

refactor: optimize UsersPage component

- Removed bulk selection and deletion functionality.
- Simplified user table structure and adjusted column spans.
- Cleaned up unused state and imports for improved clarity.
This commit is contained in:
hamed
2026-06-10 21:08:53 +03:30
parent 7fb805be27
commit 5f4a8d197b
5 changed files with 362 additions and 492 deletions
+5 -66
View File
@@ -165,18 +165,15 @@ export default function UsersPage() {
const [search, setSearch] = useState('');
const [role, setRole] = useState('');
const [status, setStatus] = useState('');
const [selected, setSelected] = useState<string[]>([]);
const [deleteTarget, setDeleteTarget] = useState<AdminUser | null>(null);
const [roleTarget, setRoleTarget] = useState<AdminUser | null>(null);
const [confirmBulkDel, setConfirmBulkDel] = useState(false);
const [bulkDeleting, setBulkDeleting] = useState(false);
const [deleteTarget, setDeleteTarget] = useState<AdminUser | null>(null);
const [roleTarget, setRoleTarget] = useState<AdminUser | null>(null);
useEffect(() => {
const t = setTimeout(() => { setSearch(searchInput); setPage(1); }, 350);
return () => clearTimeout(t);
}, [searchInput]);
useEffect(() => { setPage(1); setSelected([]); }, [role, status]);
useEffect(() => { setPage(1); }, [role, status]);
// ── Queries ──
@@ -238,27 +235,6 @@ export default function UsersPage() {
onError: (e: Error) => toast.error(e.message),
});
// ── Bulk ──
const allSelected = items.length > 0 && items.every((u) => selected.includes(u.uuid));
const toggleAll = () => setSelected(allSelected ? [] : items.map((u) => u.uuid));
const toggleOne = (uuid: string) =>
setSelected((prev) => prev.includes(uuid) ? prev.filter((id) => id !== uuid) : [...prev, uuid]);
const handleBulkDelete = async () => {
setBulkDeleting(true);
let count = 0;
for (const uuid of selected) {
try { await api.delete(`/api/v1/admin/users/${uuid}`); count++; } catch {}
}
setBulkDeleting(false);
setConfirmBulkDel(false);
setSelected([]);
toast.success(`${formatNumber(count)} کاربر حذف شد`);
qc.invalidateQueries({ queryKey: ['users'] });
qc.invalidateQueries({ queryKey: ['users-stats'] });
};
// ── KPI data ──
const kpiCards = [
@@ -335,32 +311,11 @@ export default function UsersPage() {
</div>
</div>
{/* Bulk bar */}
{selected.length > 0 && (
<div style={{
padding: '10px 16px', background: 'var(--primary-soft)',
borderBottom: '1px solid var(--border)',
display: 'flex', alignItems: 'center', gap: 12,
}}>
<span style={{ fontSize: 13, color: 'var(--primary-700)', fontWeight: 600 }}>
{formatNumber(selected.length)} کاربر انتخاب شده
</span>
<div style={{ display: 'flex', gap: 8, marginRight: 'auto' }}>
<button className="btn danger sm" onClick={() => setConfirmBulkDel(true)}>حذف انتخابشدهها</button>
<button className="btn ghost sm" onClick={() => setSelected([])}>لغو</button>
</div>
</div>
)}
{/* Table */}
<div className="table-wrap">
<table className="t">
<thead>
<tr>
<th style={{ width: 42 }}>
<input type="checkbox" checked={allSelected} onChange={toggleAll}
style={{ accentColor: 'var(--primary)', cursor: 'pointer' }} />
</th>
<th>کاربر</th>
<th>شماره موبایل</th>
<th>نقش</th>
@@ -372,7 +327,7 @@ export default function UsersPage() {
<tbody>
{usersQ.isLoading && Array.from({ length: 7 }).map((_, i) => (
<tr key={i}>
{Array.from({ length: 7 }).map((_, j) => (
{Array.from({ length: 6 }).map((_, j) => (
<td key={j}>
<div className="skeleton" style={{ height: 14, borderRadius: 6, width: j === 1 ? '70%' : '55%' }} />
</td>
@@ -382,7 +337,7 @@ export default function UsersPage() {
{!usersQ.isLoading && items.length === 0 && (
<tr>
<td colSpan={7}>
<td colSpan={6}>
<div className="empty">هیچ کاربری یافت نشد</div>
</td>
</tr>
@@ -390,11 +345,6 @@ export default function UsersPage() {
{!usersQ.isLoading && items.map((user) => (
<tr key={user.uuid}>
<td>
<input type="checkbox" checked={selected.includes(user.uuid)}
onChange={() => toggleOne(user.uuid)}
style={{ accentColor: 'var(--primary)', cursor: 'pointer' }} />
</td>
<td>
<div className="cell-user">
<UserAvatar name={user.name} id={user.id} />
@@ -454,17 +404,6 @@ export default function UsersPage() {
onCancel={() => setDeleteTarget(null)}
/>
<ConfirmDialog
open={confirmBulkDel}
title="حذف گروهی"
message={`آیا از حذف ${formatNumber(selected.length)} کاربر انتخاب‌شده اطمینان دارید؟`}
confirmLabel={`حذف ${formatNumber(selected.length)} کاربر`}
danger
loading={bulkDeleting}
onConfirm={handleBulkDelete}
onCancel={() => setConfirmBulkDel(false)}
/>
{roleTarget && (
<ChangeRoleModal
user={roleTarget}