import { useState } from 'react'; import { useNavigate, useParams } from 'react-router'; import { ChevronRightIcon, ChevronDownIcon, PlusIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import PageHeader from '../components/ui/PageHeader'; import Pagination from '../components/ui/Pagination'; import StatCard from '../components/ui/StatCard'; import StatusBadge from '../components/ui/StatusBadge'; import DataTable, { type Column } from '../components/ui/DataTable'; import { formatRial, formatDate, formatNumber } from '../lib/utils'; import { paymentMethodLabel } from '../lib/paymentMethods'; import { usePatientInvoices, MY_PAYMENTS_LIMIT, type PatientInvoiceRow, } from '../hooks/useMyPayments'; const EMPTY: PatientInvoiceRow[] = []; /** HH:MM (Persian digits) from a unix timestamp. */ function formatTime(unix: number): string { return new Intl.DateTimeFormat('fa-IR', { hour: '2-digit', minute: '2-digit' }).format(new Date(unix * 1000)); } function Avatar({ name }: { name: string | null }) { return (
{(name ?? '؟').charAt(0)}
); } function Section({ title, children }: { title: string; children: React.ReactNode }) { return (
{title}
{children}
); } /** آیتم‌های صورتحساب و پرداخت‌های ثبت‌شده‌ی آن، کنار هم در ردیف بازشونده. */ function InvoiceBreakdown({ row }: { row: PatientInvoiceRow }) { return (
{row.items.length === 0 ? ( آیتمی ثبت نشده است. ) : (
{row.items.map((it) => (
{it.title}{it.quantity > 1 ? ` × ${formatNumber(it.quantity)}` : ''} {formatRial(it.total_rials)}
))}
)}
{row.payments.length === 0 ? ( پرداختی ثبت نشده است. ) : (
{row.payments.map((p, i) => (
{paymentMethodLabel(p.method)} {formatDate(p.paid_at)} {formatRial(p.amount_rials)}
))}
)}
); } /** * پرداخت‌های ثبت‌شده‌ی یک بیمار — سربرگ بیمار، کارت‌های آمار و جدول صورتحساب‌ها * با ردیف بازشونده‌ی آیتم‌ها و روش‌های پرداخت. */ export default function MyPaymentDetailPage() { const { patientUuid } = useParams<{ patientUuid: string }>(); const navigate = useNavigate(); const [page, setPage] = useState(1); const [expanded, setExpanded] = useState(null); const { data, isLoading } = usePatientInvoices(patientUuid, page); const payload = data?.data; const patient = payload?.patient; const rows = payload?.data ?? EMPTY; const summary = payload?.summary; const total = payload?.meta?.totalRecords ?? 0; const columns: Column[] = [ { key: 'number', header: 'شماره صورتحساب', render: (r) => #{formatNumber(r.number)} }, { key: 'issued_at', header: 'تاریخ', render: (r) => formatDate(r.issued_at) }, { key: 'time', header: 'ساعت', render: (r) => {formatTime(r.issued_at)} }, { key: 'service_title', header: 'نوع خدمت', render: (r) => {r.service_title ?? '—'} }, { key: 'total_rials', header: 'مبلغ کل', render: (r) => (
{formatRial(r.total_rials)}
{r.status === 'partial' && (
پرداخت‌شده: {formatRial(r.paid_rials)}
)}
), }, { key: 'status', header: 'وضعیت', render: (r) => }, ]; return ( <> } />
{patient?.name ?? '—'}
{patient?.national_code ?? '—'}
( )} renderExpanded={(row) => (expanded === row.uuid ? : null)} /> {total > MY_PAYMENTS_LIMIT && ( )}
); }