"use client"; import { usePoll } from "@/lib/use-poll"; import type { EmailStats } from "@/lib/types"; import { StatCard } from "@/components/stat-card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { StatusBadge } from "@/components/status-badge"; interface BackupResult { host: string; status: string; last_run: string; size?: string; } interface DriftResult { stack: string; drifted: boolean; details?: string; } interface StackRestart { stack: string; status: string; timestamp: string; } const categoryColors: Record = { newsletters: "bg-blue-500/15 border-blue-500/25 text-blue-300", promotions: "bg-amber-500/15 border-amber-500/25 text-amber-300", social: "bg-purple-500/15 border-purple-500/25 text-purple-300", finance: "bg-green-500/15 border-green-500/25 text-green-300", receipts: "bg-emerald-500/15 border-emerald-500/25 text-emerald-300", travel: "bg-cyan-500/15 border-cyan-500/25 text-cyan-300", orders: "bg-orange-500/15 border-orange-500/25 text-orange-300", personal: "bg-pink-500/15 border-pink-500/25 text-pink-300", work: "bg-indigo-500/15 border-indigo-500/25 text-indigo-300", updates: "bg-teal-500/15 border-teal-500/25 text-teal-300", spam: "bg-red-500/15 border-red-500/25 text-red-300", }; function getCategoryClass(cat: string): string { const lower = cat.toLowerCase(); for (const [key, cls] of Object.entries(categoryColors)) { if (lower.includes(key)) return cls; } return "bg-white/[0.06] border-white/[0.08] text-muted-foreground"; } export default function AutomationsPage() { const { data: emails } = usePoll("/api/automations/email", 60000); const { data: backups } = usePoll>("/api/automations/backup", 120000); const { data: drift } = usePoll>("/api/automations/drift", 120000); const { data: restartsData } = usePoll<{ entries: StackRestart[] }>("/api/automations/restarts", 60000); const restarts = restartsData?.entries ?? []; // Compute stats for top row const totalEmailsToday = emails?.accounts ? emails.accounts.reduce((sum, acct) => { const today = Number((acct as Record).today ?? (acct as Record).today_total ?? 0); return sum + today; }, 0) : 0; const backupOk = String(backups?.status ?? "unknown") === "ok"; const driftStatus = String(drift?.status ?? "unknown"); const driftClean = driftStatus === "clean" || driftStatus === "no_log"; const restartCount = restarts.length; return (

Automations

{/* Top: Big stats row */}
{/* Middle: Email Organizers */} Email Organizers {!emails ? (

Loading...

) : (
{emails.accounts.map((acct: Record) => { const name = String(acct.account ?? acct.name ?? "?"); const today = Number(acct.today ?? acct.today_total ?? 0); const cats = (acct.categories ?? acct.today_categories ?? {}) as Record; return (

{name}

today

{today}

{Object.entries(cats).map(([cat, count]) => ( {cat}: {count} ))}
); })}
)}
{/* Bottom: System Health — 2 columns */}
{/* Backup Details */} Backup Details {backups && ( )} {!backups ? (

Loading...

) : (
{backups.has_errors ? (

Errors detected in backup

) : null}
Log entries today {String(backups.entries ?? 0)}
{backups.last_run ? (
Last run {String(backups.last_run)}
) : null} {backups.email_count != null ? (
Emails backed up {String(backups.email_count)}
) : null}
)}
{/* Config Drift + Restarts */} Config Drift & Restarts {/* Drift */}

Config Drift

{drift && ( )}
{drift && (

{String(drift.last_result ?? "No scan results yet")}

)}
{/* Restarts */}

Recent Restarts

{restarts.length === 0 ? (

No recent restarts

) : (
{restarts.map((r, i) => (
{r.stack}
{new Date(r.timestamp).toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", })}
))}
)}
); }