From 147ea0c318b246e1045a56e8eb33cd3719b84cb2 Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Sun, 12 Jul 2026 14:47:53 +0330 Subject: [PATCH] feat(financial-report): add filters for representation, date range, and improve data fetching --- assets/admin/pages/FinancialReportPage.tsx | 43 ++++++++++++++++++- .../admin/pages/RepresentationDetailPage.tsx | 4 +- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/assets/admin/pages/FinancialReportPage.tsx b/assets/admin/pages/FinancialReportPage.tsx index 3728ce51..9dacf947 100644 --- a/assets/admin/pages/FinancialReportPage.tsx +++ b/assets/admin/pages/FinancialReportPage.tsx @@ -5,6 +5,11 @@ import type { ApiResponse, PaginatedResponse } from '../lib/api'; import { formatRial, formatDate } from '../lib/utils'; import DataTable, { Column } from '../components/ui/DataTable'; import Pagination from '../components/ui/Pagination'; +import SearchableSelect from '../components/ui/SearchableSelect'; +import PersianDateInput from '../components/ui/PersianDateInput'; + +const dayStart = (d: string): number => Math.floor(new Date(`${d}T00:00:00`).getTime() / 1000); +const dayEnd = (d: string): number => Math.floor(new Date(`${d}T23:59:59`).getTime() / 1000); interface Breakdown { uuid: string; @@ -41,6 +46,9 @@ const SOURCE_LABEL: Record = { export default function FinancialReportPage() { const [page, setPage] = useState(1); const [source, setSource] = useState(''); + const [repId, setRepId] = useState(null); + const [fromDate, setFromDate] = useState(''); + const [toDate, setToDate] = useState(''); const limit = 15; const summaryQ = useQuery({ @@ -52,11 +60,24 @@ export default function FinancialReportPage() { // eslint-disable-next-line @typescript-eslint/no-explicit-any const summary: Summary | undefined = (summaryQ.data?.data as any)?.data ?? summaryQ.data?.data; + const repsQ = useQuery({ + queryKey: ['representations-select'], + queryFn: () => api.get>('/api/v1/admin/representations?limit=200'), + staleTime: 60_000, + }); + const repOptions = [ + { value: '', label: 'همه نمایندگان' }, + ...(repsQ.data?.data ?? []).map((r) => ({ value: r.id, label: `${r.full_name}${r.city ? ` — ${r.city}` : ''}` })), + ]; + const { data, isLoading } = useQuery({ - queryKey: ['financial-breakdowns', page, source], + queryKey: ['financial-breakdowns', page, source, repId, fromDate, toDate], queryFn: () => { const params = new URLSearchParams({ page: String(page), limit: String(limit) }); if (source) params.set('source', source); + if (repId) params.set('representation_id', String(repId)); + if (fromDate) params.set('from', String(dayStart(fromDate))); + if (toDate) params.set('to', String(dayEnd(toDate))); return api.get>(`/api/v1/admin/financial-breakdowns?${params}`); }, }); @@ -104,12 +125,30 @@ export default function FinancialReportPage() { ))} -
+
+
+
+ { setRepId(v === '' || v === null ? null : Number(v)); setPage(1); }} + placeholder="فیلتر نماینده…" + /> +
+ { setFromDate(v); setPage(1); }} placeholder="از تاریخ" max={toDate || undefined} /> + { setToDate(v); setPage(1); }} placeholder="تا تاریخ" min={fromDate || undefined} /> + {(repId || fromDate || toDate || source) && ( + + )} +
+ ( navigate(`/admin/doctors/${d.uuid}`)}> {d.name} - {d.medical_code ?? '—'} + {d.medical_code ?? '—'} {formatNumber(d.past_count)} {d.upcoming_count > 0 ? {formatNumber(d.upcoming_count)} : ۰} @@ -398,7 +398,7 @@ export default function RepresentationDetailPage() { navigate(`/admin/doctors/${a.doctor_uuid}`)}> {a.doctor_name} {a.patient_name ?? '—'} - {formatDateTime(a.slot_start)} + {formatDateTime(a.slot_start)} {a.status} ))}