'use client'; import useSWR from 'swr'; import { useApi } from '@/lib/useApi'; import { getCabinetSummary, listCabinetItems } from '@/services/cabinet'; import { listPurchases } from '@/services/purchases'; import { getRefillAlerts } from '@/services/refills'; import { listCabinetEvents } from '@/services/cabinet-events'; import { SetPageHeader } from '@/components/layout/SetPageHeader'; import { Card, CardHeader } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Pill } from '@/components/ui/Pill'; import { Icon } from '@/components/ui/Icon'; function now() { return new Date(); } function greeting() { const h = now().getHours(); if (h < 12) return 'Good morning'; if (h < 17) return 'Good afternoon'; return 'Good evening'; } function formatDate(d: Date) { return d.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' }); } export default function DashboardPage() { const { householdId, profile, isLoading } = useApi(); const name = profile?.displayName?.split(' ')[0] ?? 'there'; const { data: summary } = useSWR(householdId ? `cabinet-summary-${householdId}` : null, () => getCabinetSummary(householdId!), ); const { data: cabinetItems } = useSWR(householdId ? `cabinet-items-${householdId}` : null, () => listCabinetItems(householdId!, { limit: 10 }), ); const { data: pendingPurchases } = useSWR( householdId ? `purchases-ordered-${householdId}` : null, () => listPurchases(householdId!, { status: 'ordered', limit: 5 }), ); const { data: refillAlerts } = useSWR(householdId ? `refill-alerts-${householdId}` : null, () => getRefillAlerts(householdId!, { thresholdDays: 14 }), ); const { data: recentEvents } = useSWR(householdId ? `cabinet-events-${householdId}` : null, () => listCabinetEvents(householdId!, { limit: 5 }), ); const today = formatDate(now()); if (isLoading) { return ( <> ); } return ( <>
{/* Hero */}
{today}
{greeting()}, {name}.
{summary && (
{refillAlerts && refillAlerts.data.some((a) => a.daysUntilEmpty <= 7) ? ( Some medicines are critically low — check refills. ) : ( 'Your cabinet is in good shape.' )}
)}
{/* Cabinet stats */} {summary && (
)}
{/* Grid */}
{/* Days of supply */}
Open cabinet } />
{cabinetItems?.data.length ? ( cabinetItems.data.slice(0, 8).map((item) => (
{item.medicineName ?? 'Unknown'}
{item.quantity} {item.unit}
)) ) : ( )}
{/* Running low */}
Refills } />
{refillAlerts?.data.length ? ( refillAlerts.data.slice(0, 5).map((alert) => (
{alert.medicineName}
{alert.daysUntilEmpty}d
left
)) ) : ( )}
{/* Pending orders */}
All purchases } />
{pendingPurchases?.data.length ? ( pendingPurchases.data.map((p) => (
{p.storeName ?? 'Unknown store'}
{p.items.length} item{p.items.length > 1 ? 's' : ''}
{p.status}
)) ) : ( )}
{/* Recent activity */}
See all } />
{recentEvents?.data.length ? ( recentEvents.data.slice(0, 5).map((event) => (
{event.eventType} {event.medicineName} {new Date(event.createdAt).toLocaleDateString()}
)) ) : ( )}
); } function StatBadge({ label, value, tone, }: { label: string; value: number; tone?: 'warn' | 'danger'; }) { const color = tone === 'danger' ? 'var(--danger)' : tone === 'warn' ? 'var(--warn)' : 'var(--brand)'; return (
{value}
{label}
); } function EmptyState({ message }: { message: string }) { return (
{message}
); } function DashboardSkeleton() { return (
{[1, 2, 3].map((i) => (
))}
); }