import { useState, type ReactNode } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { formatINR } from '@sims/domain'
import { Badge, DataTable, EmptyState, ErrorState, Notice, Skeleton, StatCard, Stats } from '@sims/ui'
import { displayName, getDashboard, getSmsBalances, getStalledProjects, isManagerial } from '../api'
import { QueueActions, RULE_LABEL, reminderTone } from '../components/ReminderQueue'
import { useData } from './Clients'
const inr = (p: number) => formatINR(p)
/** 'YYYY-MM-DD' → 'Sunday 19 July 2026' (falls back to the raw string if unparseable). */
const longDate = (iso: string): string => {
const d = new Date(`${iso}T00:00:00`)
return Number.isNaN(d.getTime())
? iso
: d.toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })
}
/** 'YYYY-MM-DD' → '19 Jul' (falls back to the raw string if unparseable). */
const shortDate = (iso: string): string => {
const d = new Date(`${iso}T00:00:00`)
return Number.isNaN(d.getTime()) ? iso : d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short' })
}
/**
* Dashboard home — the "cockpit" (D29): a Today hero strip, the four KPI stat
* cards, the reminder queue, then a bento grid of the day's sections. Low-colour
* on purpose — ink + neutrals + one teal accent, red only for real failures.
*/
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 smsLow = useData(getSmsBalances, []) // D28: low-balance alert, seen even without opening the SMS screen
const stalled = useData(getStalledProjects, []) // parked onboarding — active projects with no recent progress
const [err, setErr] = useState('')
const v = dash.data
const name = displayName()
return (
)
}
/** One bento card: an uppercase-labelled header (+ count and optional link) over a
* scrollable list, or an empty-state line when there's nothing to show. */
function Card(props: {
title: string; count?: number; link?: { to: string; label?: string }
empty: string; isEmpty: boolean; children: ReactNode
}) {
return (