feat: implement filtered and paginated appointment retrieval for doctors

This commit is contained in:
hamed
2026-07-19 11:41:43 +03:30
parent f1d147f9ef
commit 8420a1a6c2
4 changed files with 279 additions and 8 deletions
@@ -3,11 +3,14 @@
* `src/components/dashboard/list/` (CustomTable + DetailT + Status).
*
* Source data was static mock; here it is fed by the real dashboard API
* (`/api/v1/dashboard/{clinic,doctor}` → `today_appointments`). Read-only —
* status display/editing lives on the appointments page, not the dashboard.
* (`/api/v1/dashboard/{clinic,doctor}` → `today_appointments`) or, when a
* `queryKey` is supplied, by the filtered doctor list endpoint. Status is
* editable in place only when the row carries a `version` (optimistic lock)
* and the parent passes the query key to invalidate.
*/
import React from 'react';
import { Link } from 'react-router-dom';
import AppointmentStatusDropdown, { STATUS_META } from '../ui/AppointmentStatusDropdown';
export interface ApptRow {
uuid: string;
@@ -18,6 +21,8 @@ export interface ApptRow {
slot_start: number;
slot_end?: number | null;
status: string;
/** لازم برای قفل خوش‌بینانهٔ PATCH وضعیت؛ نبودنش یعنی وضعیت فقط‌خواندنی است. */
version?: number;
}
/**
@@ -35,16 +40,24 @@ function formatTime(ts?: number | null): string {
return new Intl.DateTimeFormat('fa-IR', { timeZone: 'Asia/Tehran', hour: '2-digit', minute: '2-digit' }).format(new Date(ts * 1000));
}
const HEAD = ['ردیف', 'نام بیمار', 'شماره تماس', 'شروع', 'پایان', 'سرویس', 'پرسنل', 'عملیات'];
const HEAD = ['ردیف', 'نام بیمار', 'شماره تماس', 'شروع', 'پایان', 'سرویس', 'پرسنل', 'وضعیت', 'عملیات'];
export function NewAppointmentsTable({ rows, loading }: { rows: ApptRow[]; loading?: boolean }) {
interface Props {
rows: ApptRow[];
loading?: boolean;
/** کلید کوئری برای invalidate پس از تغییر وضعیت. بدون آن وضعیت فقط نمایش داده می‌شود. */
queryKey?: unknown[];
emptyText?: string;
}
export function NewAppointmentsTable({ rows, loading, queryKey, emptyText }: Props) {
if (loading) {
return <div className="skeleton h-[180px] rounded-[8px]" />;
}
if (!rows.length) {
return (
<p className="text-center py-[32px] text-[13.5px] text-[#7E7E7E] dark:text-[#A1A1A1]">
نوبتی برای امروز ثبت نشده
{emptyText ?? 'نوبتی برای امروز ثبت نشده'}
</p>
);
}