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}
}
)
}