From 432587c7a191b2abda544812a4e904bef4cc914e Mon Sep 17 00:00:00 2001 From: Thomas Joise Date: Sun, 19 Jul 2026 17:02:48 +0530 Subject: [PATCH] fix(ui): Client 360 shows documents + payments newest-first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ledger returns rows oldest-first, so 'Recent documents' sliced the OLDEST 5 and the Documents/Payments tables listed oldest→newest. Sort newest-first in the view (by date then doc-no for docs; received-on then id for payments) so recent transactions lead. Frontend-only; no shared query/test touched. Co-Authored-By: Claude Fable 5 --- apps/hq-web/src/pages/ClientDetail.tsx | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/apps/hq-web/src/pages/ClientDetail.tsx b/apps/hq-web/src/pages/ClientDetail.tsx index 35f96ff..8d0df8c 100644 --- a/apps/hq-web/src/pages/ClientDetail.tsx +++ b/apps/hq-web/src/pages/ClientDetail.tsx @@ -86,6 +86,10 @@ export function ClientDetail() { modules.data?.find((m) => m.id === moduleId)?.name ?? moduleId const docs = ledger.data?.documents ?? [] + // The ledger is oldest-first; the register + "recent" views want newest first (by date, then doc no). + const docsNewest = [...docs] + .sort((a, b) => (a.docDate === b.docDate ? (b.docNo ?? '').localeCompare(a.docNo ?? '') : b.docDate.localeCompare(a.docDate))) + const recentDocs = docsNewest.slice(0, 5) const openDocs = docs.filter((d) => d.status === 'draft' || d.status === 'sent' || d.status === 'part_paid') const activeModules = (cms.data ?? []).filter((m) => m.active) const lastInteraction = interactions.data?.[0]?.onDate @@ -228,8 +232,8 @@ export function ClientDetail() { { key: 'date', label: 'Date' }, { key: 'payable', label: 'Payable', numeric: true }, { key: 'status', label: 'Status' }, ]} - onRowClick={(_row, i) => nav(`/documents/${docs[i]!.id}`)} - rows={docs.slice(0, 5).map((d) => ({ + onRowClick={(_row, i) => nav(`/documents/${recentDocs[i]!.id}`)} + rows={recentDocs.map((d) => ({ no: d.docNo ?? 'draft', type: {DOC_TYPE_LABEL[d.docType]}, date: d.docDate, @@ -359,15 +363,15 @@ export function ClientDetail() { <> {ledger.error !== undefined && } {ledger.data === undefined && ledger.error === undefined ? - : docs.length === 0 ? No documents yet — compose one from New Document. : ( + : docsNewest.length === 0 ? No documents yet — compose one from New Document. : ( nav(`/documents/${docs[i]!.id}`)} - rows={docs.map((d) => ({ + onRowClick={(_row, i) => nav(`/documents/${docsNewest[i]!.id}`)} + rows={docsNewest.map((d) => ({ no: d.docNo ?? draft, type: {DOC_TYPE_LABEL[d.docType]}, date: d.docDate, @@ -395,10 +399,12 @@ export function ClientDetail() { { key: 'amount', label: 'Amount', numeric: true }, { key: 'tds', label: 'TDS', numeric: true }, ]} - rows={ledger.data.payments.map((p) => ({ - on: p.receivedOn, mode: p.mode, ref: p.reference !== '' ? p.reference : '—', - amount: inr(p.amountPaise), tds: p.tdsPaise > 0 ? inr(p.tdsPaise) : '—', - }))} + rows={[...ledger.data.payments] + .sort((a, b) => (a.receivedOn === b.receivedOn ? (a.id < b.id ? 1 : -1) : b.receivedOn.localeCompare(a.receivedOn))) + .map((p) => ({ + on: p.receivedOn, mode: p.mode, ref: p.reference !== '' ? p.reference : '—', + amount: inr(p.amountPaise), tds: p.tdsPaise > 0 ? inr(p.tdsPaise) : '—', + }))} /> )}

Recurring plans