feat: enhance NewAppointmentsTable with dynamic patient record navigation and update DashboardPage tests

This commit is contained in:
hamed
2026-07-29 21:15:09 +03:30
parent 684cf1f783
commit 6ec011e3ad
3 changed files with 79 additions and 31 deletions
@@ -8,9 +8,11 @@
* 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 React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { toast } from 'sonner';
import AppointmentStatusDropdown, { STATUS_META } from '../ui/AppointmentStatusDropdown';
import { findRecordUuid } from '../AppointmentActions';
export interface ApptRow {
uuid: string;
@@ -95,12 +97,7 @@ export function NewAppointmentsTable({ rows, loading, queryKey, emptyText }: Pro
: <StatusPill status={r.status} />}
</Cell>
<td className="py-[10px] px-[18px] text-center">
<Link
to={isoDay(r.slot_start) ? `/admin/appointments?date=${isoDay(r.slot_start)}` : '/admin/appointments'}
className="text-[var(--primary)] text-[12px] font-medium hover:underline whitespace-nowrap"
>
مشاهده
</Link>
<ViewLink row={r} />
</td>
</tr>
))}
@@ -110,6 +107,46 @@ export function NewAppointmentsTable({ rows, loading, queryKey, emptyText }: Pro
);
}
/**
* وضعیت‌هایی که نوبت از مرحلهٔ «قطعی‌شدن» رد شده — در این‌ها پروندهٔ بیمار حتماً
* ساخته شده است (ساخت پرونده اثر جانبیِ قطعی‌کردن است).
*/
const CONFIRMED_STATUSES = ['confirmed', 'following_up', 'salon', 'completed', 'no_show'];
/**
* «مشاهده» — نوبتِ قطعی‌شده به **پروندهٔ بیمار** می‌رود (چون از لحظهٔ قطعی‌شدن پرونده
* دارد)، بقیه به لیست نوبت‌های همان روز. uuid پرونده روی ردیف نیست، پس با موبایلِ
* بیمار resolve می‌شود — همان مسیری که منوی عملیات نوبت‌ها استفاده می‌کند.
*/
function ViewLink({ row }: { row: ApptRow }) {
const navigate = useNavigate();
const [busy, setBusy] = useState(false);
const dayHref = isoDay(row.slot_start) ? `/admin/appointments?date=${isoDay(row.slot_start)}` : '/admin/appointments';
const cls = 'text-[var(--primary)] text-[12px] font-medium hover:underline whitespace-nowrap';
if (!CONFIRMED_STATUSES.includes(row.status) || !row.patient_mobile) {
return <Link to={dayHref} className={cls}>مشاهده</Link>;
}
const openRecord = async () => {
setBusy(true);
try {
const recordUuid = await findRecordUuid(row.patient_mobile!);
navigate(recordUuid ? `/admin/patients/${recordUuid}` : dayHref);
} catch {
toast.error('خطا در یافتن پرونده بیمار');
} finally {
setBusy(false);
}
};
return (
<button type="button" onClick={openRecord} disabled={busy} className={`${cls} bg-transparent border-none cursor-pointer`}>
{busy ? '...' : 'مشاهده'}
</button>
);
}
/** نمایش فقط‌خواندنی وضعیت — وقتی version یا queryKey در دسترس نیست. */
function StatusPill({ status }: { status: string }) {
const meta = STATUS_META[status] ?? { label: status, color: 'var(--text-3)' };