feat(doctors): add city and province filters for doctor listing
This commit is contained in:
@@ -107,6 +107,8 @@ export default function DoctorsPage() {
|
||||
const [status, setStatus] = useState('');
|
||||
const [ownerStatus, setOwnerStatus] = useState('');
|
||||
const [specialtyId, setSpecialty] = useState('');
|
||||
const [provinceId, setProvinceId] = useState('');
|
||||
const [cityId, setCityId] = useState('');
|
||||
const [view, setView] = useState<'table' | 'grid'>('table');
|
||||
const [deleteTarget, setDeleteTarget] = useState<AdminDoctor | null>(null);
|
||||
|
||||
@@ -115,7 +117,7 @@ export default function DoctorsPage() {
|
||||
return () => clearTimeout(t);
|
||||
}, [searchInput]);
|
||||
|
||||
useEffect(() => { setPage(1); }, [status, ownerStatus, specialtyId]);
|
||||
useEffect(() => { setPage(1); }, [status, ownerStatus, specialtyId, provinceId, cityId]);
|
||||
|
||||
// ── Queries ──
|
||||
|
||||
@@ -136,14 +138,29 @@ export default function DoctorsPage() {
|
||||
staleTime: 300_000,
|
||||
});
|
||||
|
||||
const provincesQ = useQuery({
|
||||
queryKey: ['provinces-list'],
|
||||
queryFn: () => api.get<ApiResponse<{ id: number; name: string }[]>>('/api/v1/provinces'),
|
||||
staleTime: 600_000,
|
||||
enabled: !isRepresentation,
|
||||
});
|
||||
const citiesQ = useQuery({
|
||||
queryKey: ['cities-list', provinceId],
|
||||
queryFn: () => api.get<ApiResponse<{ id: number; name: string }[]>>(`/api/v1/cities${provinceId ? `?province_id=${provinceId}` : ''}`),
|
||||
staleTime: 600_000,
|
||||
enabled: !isRepresentation && !!provinceId,
|
||||
});
|
||||
|
||||
const doctorsQ = useQuery({
|
||||
queryKey: ['admin-doctors', page, limit, search, status, ownerStatus, specialtyId],
|
||||
queryKey: ['admin-doctors', page, limit, search, status, ownerStatus, specialtyId, provinceId, cityId],
|
||||
queryFn: () => {
|
||||
const p = new URLSearchParams({ page: String(page), limit: String(limit) });
|
||||
if (search) p.set('search', search);
|
||||
if (status) p.set('status', status);
|
||||
if (ownerStatus && !isRepresentation) p.set('owner_status', ownerStatus);
|
||||
if (specialtyId) p.set('specialty_id', specialtyId);
|
||||
if (provinceId && !isRepresentation) p.set('state_id', provinceId);
|
||||
if (cityId && !isRepresentation) p.set('city_id', cityId);
|
||||
const base = isRepresentation ? '/api/v1/representation/doctors' : '/api/v1/admin/doctors';
|
||||
return api.get<PaginatedResponse<AdminDoctor>>(`${base}?${p}`);
|
||||
},
|
||||
@@ -159,6 +176,14 @@ export default function DoctorsPage() {
|
||||
() => (specialtiesQ.data?.data as any)?.data ?? specialtiesQ.data?.data ?? [],
|
||||
[specialtiesQ.data]
|
||||
);
|
||||
const provinceOptions = useMemo(
|
||||
() => ((provincesQ.data?.data as any)?.data ?? provincesQ.data?.data ?? []).map((p: { id: number; name: string }) => ({ value: String(p.id), label: p.name })),
|
||||
[provincesQ.data]
|
||||
);
|
||||
const cityOptions = useMemo(
|
||||
() => ((citiesQ.data?.data as any)?.data ?? citiesQ.data?.data ?? []).map((c: { id: number; name: string }) => ({ value: String(c.id), label: c.name })),
|
||||
[citiesQ.data]
|
||||
);
|
||||
|
||||
// ── Mutations ──
|
||||
|
||||
@@ -259,6 +284,30 @@ export default function DoctorsPage() {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!isRepresentation && (
|
||||
<div style={{ minWidth: 170 }}>
|
||||
<SearchableSelect
|
||||
options={provinceOptions}
|
||||
value={provinceId || null}
|
||||
onChange={(v) => { setProvinceId(v ? String(v) : ''); setCityId(''); }}
|
||||
placeholder="همه استانها"
|
||||
isClearable
|
||||
height={36}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!isRepresentation && provinceId && (
|
||||
<div style={{ minWidth: 170 }}>
|
||||
<SearchableSelect
|
||||
options={cityOptions}
|
||||
value={cityId || null}
|
||||
onChange={(v) => setCityId(v ? String(v) : '')}
|
||||
placeholder="همه شهرها"
|
||||
isClearable
|
||||
height={36}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="seg">
|
||||
<button className={!status ? 'on' : ''} onClick={() => setStatus('')}>همه</button>
|
||||
<button className={status === 'active' ? 'on' : ''} onClick={() => setStatus('active')}>فعال</button>
|
||||
|
||||
Reference in New Issue
Block a user