feat: implement useUrlState hook for managing URL-based state in admin pages
- Refactor multiple admin pages (BlogsPage, ClinicsPage, DoctorsPage, etc.) to utilize the new useUrlState hook for managing pagination, search, and filter states via URL. - Ensure that the state persists in the URL, allowing users to return to the same state when navigating back from detail pages. - Update relevant components to handle state changes appropriately and maintain clean URLs by removing default values. - Add SlotPicker component for selecting appointment slots based on availability. - Create tests for useUrlState to validate its functionality and ensure correct behavior when interacting with the URL. - Update API documentation to reflect changes in appointment creation and slot selection processes.
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
} from '@heroicons/react/24/outline';
|
||||
import { toast } from 'sonner';
|
||||
import { api } from '../lib/api';
|
||||
import { useUrlState, pageOf } from '../hooks/useUrlState';
|
||||
import Portal from '../components/ui/Portal';
|
||||
import type { ApiResponse, PaginatedResponse } from '../lib/api';
|
||||
import { formatDate, formatNumber, maskMobile } from '../lib/utils';
|
||||
@@ -170,22 +171,27 @@ export default function UsersPage() {
|
||||
const navigate = useNavigate();
|
||||
const qc = useQueryClient();
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
// وضعیت لیست در URL میماند تا «بازگشت» از پروفایل کاربر، همین فیلترها و صفحه را برگرداند.
|
||||
const [urlState, setUrlState] = useUrlState({ page: '1', search: '', role: '', status: '' });
|
||||
const page = pageOf(urlState.page);
|
||||
const search = urlState.search;
|
||||
const role = urlState.role;
|
||||
const status = urlState.status;
|
||||
const setPage = (p: number) => setUrlState({ page: String(p) });
|
||||
const setRole = (v: string) => setUrlState({ role: v, page: '1' });
|
||||
const setStatus = (v: string) => setUrlState({ status: v, page: '1' });
|
||||
|
||||
const [limit] = useState(25);
|
||||
const [searchInput, setSearchInput] = useState('');
|
||||
const [search, setSearch] = useState('');
|
||||
const [role, setRole] = useState('');
|
||||
const [status, setStatus] = useState('');
|
||||
// فیلد جستجو local میماند (تایپ روان)؛ مقدارِ debounceشده به URL میرود.
|
||||
const [searchInput, setSearchInput] = useState(urlState.search);
|
||||
const [deleteTarget, setDeleteTarget] = useState<AdminUser | null>(null);
|
||||
const [roleTarget, setRoleTarget] = useState<AdminUser | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => { setSearch(searchInput); setPage(1); }, 350);
|
||||
const t = setTimeout(() => setUrlState({ search: searchInput, page: '1' }), 350);
|
||||
return () => clearTimeout(t);
|
||||
}, [searchInput]);
|
||||
|
||||
useEffect(() => { setPage(1); }, [role, status]);
|
||||
|
||||
// ── Queries ──
|
||||
|
||||
const statsQ = useQuery({
|
||||
|
||||
Reference in New Issue
Block a user