import { Link } from 'react-router-dom' import { BellRing, Boxes, CalendarClock, Files, Filter, LayoutDashboard, MessageSquare, Users, Wrench, type LucideIcon, } from 'lucide-react' import { displayName, getDashboard, getPipeline, getSmsBalances, getTickets } from '../api' import { useData } from './Clients' type Tone = 'warn' | 'err' interface Stat { text: string; tone?: Tone } interface HubCard { to: string; label: string; desc: string; icon: LucideIcon; stat?: Stat } /** * Home hub (D30) — a quick-access launcher for the sections used day to day. Not * every screen (the sidebar has those); just the main ones, each a big target with * a live count so the landing doubles as a status board. */ export function Home() { const name = displayName() const dash = useData(() => getDashboard(false), []) const sms = useData(getSmsBalances, []) const tickets = useData(() => getTickets({ status: 'open' }), []) const pipeline = useData(() => getPipeline({ filter: 'all' }), []) const d = dash.data const remStat: Stat | undefined = d === undefined ? undefined : d.totals.failed > 0 ? { text: `${d.totals.failed} failed · ${d.totals.queued} queued`, tone: 'err' } : { text: `${d.totals.queued} queued` } const renewStat: Stat | undefined = d !== undefined && d.renewalsThisMonth.length > 0 ? { text: `${d.renewalsThisMonth.length} this month`, tone: 'warn' } : undefined const smsStat: Stat | undefined = sms.data !== undefined && sms.data.lowCount > 0 ? { text: `${sms.data.lowCount} low`, tone: 'warn' } : undefined const ticketStat: Stat | undefined = tickets.data !== undefined && tickets.data.total > 0 ? { text: `${tickets.data.total} open` } : undefined const pipeStat: Stat | undefined = pipeline.data !== undefined && pipeline.data.total > 0 ? { text: `${pipeline.data.total} open` } : undefined // Main, look-at-it-all-the-time sections only — the rest live in the sidebar. const cards: HubCard[] = [ { to: '/dashboard', label: 'Dashboard', desc: 'Today’s money — dues, renewals, follow-ups, the send queue.', icon: LayoutDashboard, stat: { text: 'My Day' } }, { to: '/clients', label: 'Clients', desc: 'The client book — profiles, modules, ledger, support.', icon: Users }, { to: '/documents', label: 'Documents', desc: 'Quotations, proformas, invoices, credit notes.', icon: Files }, { to: '/reminders', label: 'Reminders', desc: 'The email send queue — preview, send, dismiss.', icon: BellRing, ...(remStat !== undefined ? { stat: remStat } : {}) }, { to: '/renewals', label: 'Renewals', desc: 'AMC and module renewals — one-click renewal quotes.', icon: CalendarClock, ...(renewStat !== undefined ? { stat: renewStat } : {}) }, { to: '/pipeline', label: 'Pipeline', desc: 'Leads and quotes in flight, with next-action nudges.', icon: Filter, ...(pipeStat !== undefined ? { stat: pipeStat } : {}) }, { to: '/tickets', label: 'Tickets', desc: 'Support desk with SLA aging and overdue flags.', icon: Wrench, ...(ticketStat !== undefined ? { stat: ticketStat } : {}) }, { to: '/sms-balances', label: 'SMS credits', desc: 'Client SMS balances and top-ups.', icon: MessageSquare, ...(smsStat !== undefined ? { stat: smsStat } : {}) }, { to: '/modules', label: 'Modules', desc: 'Sellable modules with the dated price book.', icon: Boxes }, ] return (

Welcome back{name !== '' ? `, ${name}` : ''}

Your most-used areas — everything else is in the sidebar.

{cards.map((c) => ( {c.label} {c.desc} {c.stat !== undefined && ( {c.stat.text} )} ))}
) }