feat(dashboard): enhance appointment table and link to specific dates

This commit is contained in:
hamed
2026-07-18 21:54:08 +03:30
parent 62a9fd87c3
commit 4ce1b39a83
5 changed files with 81 additions and 73 deletions
@@ -20,6 +20,16 @@ export interface ApptRow {
status: string;
}
/**
* روزِ محلیِ نوبت (YYYY-MM-DD) برای دیپ‌لینک «مشاهده» به همان تاریخ در لیست نوبت‌ها.
* همان قراردادی که AppointmentDetailPage/AppointmentsPage استفاده می‌کنند.
*/
const isoDay = (ts?: number | null): string => {
if (!ts) return '';
const d = new Date(ts * 1000);
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
};
function formatTime(ts?: number | null): string {
if (!ts) return '—';
return new Intl.DateTimeFormat('fa-IR', { timeZone: 'Asia/Tehran', hour: '2-digit', minute: '2-digit' }).format(new Date(ts * 1000));
@@ -46,7 +56,7 @@ export function NewAppointmentsTable({ rows, loading }: { rows: ApptRow[]; loadi
{HEAD.map((h, i) => (
<th
key={h}
className={`text-[#616161] dark:text-[#D7D8ED] text-[14px] font-normal py-[10px] px-[18px] whitespace-nowrap ${i === 0 ? 'text-right' : 'text-start'}`}
className={`text-[#616161] dark:text-[#D7D8ED] text-[14px] font-normal py-[10px] px-[18px] whitespace-nowrap ${i === HEAD.length - 1 ? 'text-center' : 'text-start'}`}
>
{h}
</th>
@@ -59,16 +69,16 @@ export function NewAppointmentsTable({ rows, loading }: { rows: ApptRow[]; loadi
key={r.uuid}
className="border-b border-[#DBDBDB] dark:border-transparent hover:bg-[#f4f5fd] dark:hover:bg-[#2a2c3d] transition-colors"
>
<Cell className="text-right">{new Intl.NumberFormat('fa-IR').format(idx + 1)}</Cell>
<Cell className="text-start">{r.patient_name || '—'}</Cell>
<Cell className="text-start" dir="ltr">{r.patient_mobile || '—'}</Cell>
<Cell className="text-right" dir="ltr">{formatTime(r.slot_start)}</Cell>
<Cell className="text-right" dir="ltr">{formatTime(r.slot_end)}</Cell>
<Cell className="text-right">{r.service_name || '—'}</Cell>
<Cell className="text-start">{r.doctor_name ? `دکتر ${r.doctor_name}` : '—'}</Cell>
<Cell>{new Intl.NumberFormat('fa-IR').format(idx + 1)}</Cell>
<Cell>{r.patient_name || '—'}</Cell>
<Cell>{r.patient_mobile ? <bdi dir="ltr">{r.patient_mobile}</bdi> : '—'}</Cell>
<Cell><bdi dir="ltr">{formatTime(r.slot_start)}</bdi></Cell>
<Cell><bdi dir="ltr">{formatTime(r.slot_end)}</bdi></Cell>
<Cell>{r.service_name || '—'}</Cell>
<Cell>{r.doctor_name ? `دکتر ${r.doctor_name}` : '—'}</Cell>
<td className="py-[10px] px-[18px] text-center">
<Link
to="/admin/appointments"
to={isoDay(r.slot_start) ? `/admin/appointments?date=${isoDay(r.slot_start)}` : '/admin/appointments'}
className="text-[#5559ce] text-[12px] font-medium hover:underline whitespace-nowrap"
>
مشاهده
@@ -82,11 +92,11 @@ export function NewAppointmentsTable({ rows, loading }: { rows: ApptRow[]; loadi
);
}
function Cell({ children, className = '', dir }: { children: React.ReactNode; className?: string; dir?: 'ltr' | 'rtl' }) {
/** همه‌ی سلول‌ها text-start هستند تا دقیقاً زیر هدر هم‌نامشان بنشینند. */
function Cell({ children, className = '' }: { children: React.ReactNode; className?: string }) {
return (
<td
dir={dir}
className={`text-[#616161] dark:text-[#A1A1A1] text-[16px] font-medium py-[10px] px-[18px] whitespace-nowrap ${className}`}
className={`text-[#616161] dark:text-[#A1A1A1] text-[16px] font-medium py-[10px] px-[18px] whitespace-nowrap text-start ${className}`}
>
{children}
</td>