import { useState, type ReactNode } from 'react' import { Link, useNavigate } from 'react-router-dom' import { formatINR } from '@sims/domain' import { Badge, DataTable, EmptyState, ErrorState, Notice, PageHeader, Skeleton, StatCard, Stats } from '@sims/ui' import { getDashboard, isManagerial } from '../api' import { QueueActions, RULE_LABEL, reminderTone } from '../components/ReminderQueue' import { useData } from './Clients' const inr = (p: number) => formatINR(p) /** Dashboard home — today's money + the manual reminder queue (spec §3). */ export function Dashboard() { const nav = useNavigate() // My Day (D18 WS-E): owner/manager toggle Mine ↔ Everyone; staff are always // scoped to their own book server-side, so they get no toggle. const managerial = isManagerial() const [mine, setMine] = useState(false) const dash = useData(() => getDashboard(mine), [mine]) const [err, setErr] = useState('') const v = dash.data return (
), } : {})} /> {dash.error !== undefined && } {err !== '' && {err}} {v === undefined && dash.error === undefined ? : v === undefined ? null : ( <> 0 ? { hint: 'needs attention', hintTone: 'err' as const } : {})} />

Reminder queue View all →

{v.queue.length === 0 ? Nothing waiting — all clear. : ( { const s = v.queue[i]?.status return s === 'failed' ? 'err' : undefined }} rows={v.queue.map((rem) => ({ kind: rem.label !== '' ? rem.label : RULE_LABEL[rem.ruleKind] ?? rem.ruleKind, client: rem.clientName, ref: rem.docNo ?? rem.duePeriod, status: {rem.status}, error: rem.error ?? '—', act: , }))} /> )} {v.queueTotal > v.queue.length && ( // No silent caps (rule 8): the table is the first page only — say so.

Showing {v.queue.length} of {v.queueTotal} — see the full queue.

)}
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' })} />
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 : '—' })} />
({ client: p.clientName, on: p.receivedOn, mode: p.mode, amt: inr(p.amountPaise) })} />
)}
) } /** A titled table with an empty state — keeps the dashboard body declarative. */ function Section(props: { title: string; empty: string; rows: T[] columns: { key: string; label: string; numeric?: boolean }[] map: (row: T) => Record; onRowClick?: (i: number) => void }) { return ( <>

{props.title}

{props.rows.length === 0 ? {props.empty} : ( props.onRowClick!(i) } : {})} rows={props.rows.map(props.map)} /> )} ) }