diff --git a/apps/hq-web/src/pages/Dashboard.tsx b/apps/hq-web/src/pages/Dashboard.tsx index 9d38396..6c5684d 100644 --- a/apps/hq-web/src/pages/Dashboard.tsx +++ b/apps/hq-web/src/pages/Dashboard.tsx @@ -1,7 +1,7 @@ import { useState, type ReactNode } from 'react' import { useNavigate } from 'react-router-dom' import { formatINR } from '@sims/domain' -import { Badge, Button, DataTable, EmptyState, Notice, PageHeader, StatCard, Stats } from '@sims/ui' +import { Badge, Button, DataTable, EmptyState, ErrorState, Notice, PageHeader, Skeleton, StatCard, Stats } from '@sims/ui' import { getDashboard, sendReminder, dismissReminder, getReminderPreview, type Reminder } from '../api' import { useData } from './Clients' @@ -25,14 +25,14 @@ export function Dashboard() { return (
- {dash.error !== undefined && {dash.error}} + {dash.error !== undefined && } {err !== '' && {err}} - {v === undefined ? Loading… : ( + {v === undefined && dash.error === undefined ? : v === undefined ? null : ( <> - + 0 ? { hint: 'needs attention', hintTone: 'err' as const } : {})} /> @@ -44,6 +44,10 @@ export function Dashboard() { { key: 'ref', label: 'Reference' }, { key: 'status', label: 'Status' }, { key: 'error', label: 'Error' }, { key: 'act', label: '' }, ]} + rowTone={(i) => { + const s = v.queue[i]?.status + return s === 'failed' ? 'err' : undefined + }} rows={v.queue.map((rem) => ({ kind: RULE_LABEL[rem.ruleKind] ?? rem.ruleKind, client: rem.clientName, @@ -60,23 +64,33 @@ export function Dashboard() { onRowClick={(i) => nav(`/documents/${v.overdue[i]!.docId}`)} map={(o) => ({ no: o.docNo ?? '—', client: o.clientName, days: o.daysOverdue, due: inr(o.outstandingPaise) })} /> -
({ client: d.clientName, on: d.nextRun, amt: d.amountPaise !== null ? inr(d.amountPaise) : 'from price book' })} /> +
+
+
({ client: d.clientName, on: d.nextRun, amt: d.amountPaise !== null ? inr(d.amountPaise) : 'from price book' })} /> +
-
nav(`/clients/${v.renewalsThisMonth[i]!.clientId}`)} - map={(r) => ({ client: r.clientName, on: r.nextRenewal })} /> +
+
nav(`/clients/${v.renewalsThisMonth[i]!.clientId}`)} + map={(r) => ({ client: r.clientName, on: r.nextRenewal })} /> +
-
nav(`/clients/${v.followUpsToday[i]!.clientId}`)} - map={(f) => ({ client: f.clientName, on: f.followUpOn, notes: f.notes !== '' ? f.notes : '—' })} /> +
+
nav(`/clients/${v.followUpsToday[i]!.clientId}`)} + map={(f) => ({ client: f.clientName, on: f.followUpOn, notes: f.notes !== '' ? f.notes : '—' })} /> +
-
({ client: p.clientName, on: p.receivedOn, mode: p.mode, amt: inr(p.amountPaise) })} /> +
+
({ client: p.clientName, on: p.receivedOn, mode: p.mode, amt: inr(p.amountPaise) })} /> +
+
)}
diff --git a/packages/ui/src/components.tsx b/packages/ui/src/components.tsx index 1e3b6fc..38e5f2e 100644 --- a/packages/ui/src/components.tsx +++ b/packages/ui/src/components.tsx @@ -93,12 +93,12 @@ export function DataTable(props: { ) } -export function StatCard(props: { label: string; value: ReactNode; hint?: string }) { +export function StatCard(props: { label: string; value: ReactNode; hint?: string; hintTone?: 'ok' | 'warn' | 'err' }) { return (
{props.label}
{props.value}
- {props.hint !== undefined &&
{props.hint}
} + {props.hint !== undefined &&
{props.hint}
}
) }