feat(representation): expose doctor representation details and add counts in admin views

This commit is contained in:
hamed
2026-07-12 13:00:49 +03:30
parent 476d5bb80e
commit 1a8b3bfa53
10 changed files with 366 additions and 4 deletions
@@ -13,6 +13,18 @@ import ConfirmDialog from '../components/ui/ConfirmDialog';
import Modal from '../components/ui/Modal';
import SearchableSelect from '../components/ui/SearchableSelect';
interface RepDoctor {
uuid: string;
id: number;
name: string;
gender: string | null;
medical_code: string | null;
is_active: boolean;
owner_status?: string;
appointment_count: number;
created_at: string;
}
function DetailRow({ label, value }: { label: string; value: React.ReactNode }) {
return (
<div className="cp-info-row items-start gap-4">
@@ -45,6 +57,14 @@ export default function RepresentationDetailPage() {
const rep: Representation | undefined = (data?.data as any)?.data ?? data?.data;
const doctorsQuery = useQuery({
queryKey: ['representation-doctors', uuid],
queryFn: () => api.get<PaginatedResponse<RepDoctor>>(`/api/v1/admin/representations/${uuid}/doctors?limit=100`),
enabled: !!uuid,
});
const repDoctors: RepDoctor[] = doctorsQuery.data?.data ?? [];
const repDoctorsTotal = doctorsQuery.data?.meta?.totalRecords ?? repDoctors.length;
const updateMutation = useMutation({
mutationFn: (d: Partial<Representation>) =>
api.patch<ApiResponse<Representation>>(`/api/v1/representation/${uuid}`, d),
@@ -214,6 +234,42 @@ export default function RepresentationDetailPage() {
</div>
</div>
{/* Doctors of this representation */}
<div className="cp-card p-6 mt-5">
<div className="flex items-center justify-between mb-4">
<h2 className="text-sm font-semibold text-gray-700">پزشکان این نماینده</h2>
<span className="badge blue">{formatNumber(repDoctorsTotal)} پزشک</span>
</div>
{doctorsQuery.isLoading ? (
<p className="text-sm text-gray-400 text-center py-6">در حال بارگذاری</p>
) : repDoctors.length === 0 ? (
<p className="text-sm text-gray-400 text-center py-6">این نماینده پزشکی ندارد</p>
) : (
<div style={{ overflowX: 'auto' }}>
<table style={{ width: '100%' }}>
<thead>
<tr>
<th>نام</th>
<th>کد نظام</th>
<th>تعداد نوبت</th>
<th>وضعیت</th>
</tr>
</thead>
<tbody>
{repDoctors.map((d) => (
<tr key={d.uuid} style={{ cursor: 'pointer' }} onClick={() => navigate(`/admin/doctors/${d.uuid}`)}>
<td><b>{d.name}</b></td>
<td dir="ltr" style={{ fontFamily: 'monospace' }}>{d.medical_code ?? '—'}</td>
<td>{formatNumber(d.appointment_count)}</td>
<td><ActiveBadge active={d.is_active} /></td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
{/* Edit Modal */}
<Modal open={editOpen} title="ویرایش نماینده"
onClose={() => setEditOpen(false)}