import Link from "next/link"; import { WifiIcon, BellIcon, ActivityIcon, CheckCircle2Icon, AlertTriangleIcon, XCircleIcon, MinusCircleIcon, Trash2Icon, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, CardDescription, } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { clearHistoryAction } from "@/actions/history"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { getSeededOperator } from "@/lib/operator"; import { getDashboardStats } from "@/lib/queries"; // --------------------------------------------------------------------------- // Relative time helper (no external dep, server-safe) // --------------------------------------------------------------------------- function relativeTime(date: Date | string): string { const d = typeof date === "string" ? new Date(date) : date; const diffMs = Date.now() - d.getTime(); const diffSec = Math.floor(diffMs / 1000); const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" }); if (diffSec < 60) return rtf.format(-diffSec, "second"); if (diffSec < 3600) return rtf.format(-Math.floor(diffSec / 60), "minute"); if (diffSec < 86400) return rtf.format(-Math.floor(diffSec / 3600), "hour"); return rtf.format(-Math.floor(diffSec / 86400), "day"); } // --------------------------------------------------------------------------- // Run-status pill // --------------------------------------------------------------------------- const RUN_STATUS_CONFIG: Record< string, { label: string; className: string; icon: React.ElementType } > = { success: { label: "Success", className: "bg-emerald-500/15 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-400 border-transparent", icon: CheckCircle2Icon, }, partial: { label: "Partial", className: "bg-amber-500/15 text-amber-700 dark:bg-amber-500/20 dark:text-amber-400 border-transparent", icon: AlertTriangleIcon, }, failed: { label: "Failed", className: "bg-red-500/15 text-red-600 dark:bg-red-500/20 dark:text-red-400 border-transparent", icon: XCircleIcon, }, skipped: { label: "Skipped", className: "bg-slate-200/60 text-slate-500 dark:bg-slate-700/40 dark:text-slate-400 border-transparent", icon: MinusCircleIcon, }, }; function RunStatusBadge({ status }: { status: string }) { const cfg = RUN_STATUS_CONFIG[status] ?? { label: status, className: "bg-secondary text-secondary-foreground border-transparent", icon: ActivityIcon, }; const Icon = cfg.icon; return ( {cfg.label} ); } // --------------------------------------------------------------------------- // Stat card — entire card is the link to its tab // --------------------------------------------------------------------------- function StatCard({ title, value, icon: Icon, description, href, }: { title: string; value: string | number; icon: React.ElementType; description?: string; href: string; }) { return (
{title}

{value}

{description && ( {description} )}
); } // --------------------------------------------------------------------------- // Page // --------------------------------------------------------------------------- export default async function DashboardPage() { const op = await getSeededOperator(); const stats = await getDashboardStats(op.id); const hasRuns = stats.recentRuns.length > 0; return (

Dashboard

{/* Stat cards — click to drill into the corresponding tab */}
{/* Recent activity */}

Recent activity

{hasRuns && ( Clear all run history? This permanently removes every reminder run record, including runs from reminders that have already been deleted. Reminders themselves are not affected.
)}
{hasRuns ? ( <> {/* Mobile: card list — clickable when the reminder still exists */}
{stats.recentRuns.map((run) => { const body = (

{run.name} {run.is_deleted && ( (deleted) )}

{relativeTime(run.fired_at)}

); return run.reminder_id && !run.is_deleted ? ( {body} ) : (
{body}
); })}
{/* Desktop: table — rows are clickable when reminder still exists */}
Reminder Status Fired {stats.recentRuns.map((run) => { const clickable = run.reminder_id && !run.is_deleted; return ( {clickable ? ( {run.name} ) : ( {run.name} )} {relativeTime(run.fired_at)} ); })}
) : (

No reminders have fired yet.

Schedule one to start sending WhatsApp messages.

)}
); }