import { useCallback, useEffect, useMemo, useState } from "react" import { Link } from "react-router" import { Activity, AlertTriangle, Building2, CheckCircle2, CircleAlert, HeartPulse, RefreshCw, Users as UsersIcon, } from "lucide-react" import { ArcadiaError, useArcadiaClient } from "@crema/arcadia-client" import { AlertBanner } from "@crema/feedback-ui" import { AppShell } from "~/components/layout/app-shell" import { PageHeader } from "~/components/layout/page-header" import { Button } from "~/components/ui/button" import { Skeleton } from "~/components/ui/skeleton" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card" import { listAuditLogs, type AuditLog } from "~/lib/arcadia/audit-logs" import { getHealth, SUBSYSTEMS, type HealthStatus, type HealthSubsystem, type OverallHealth, } from "~/lib/arcadia/health" import { listTenants, type Tenant } from "~/lib/arcadia/tenants" import { listUsers, type User } from "~/lib/arcadia/users" import { useRegisterContext } from "@crema/aifirst-ui/context" import { pageTitle } from "~/lib/page-meta" import { useSession } from "~/lib/session" export const meta = () => pageTitle("Overview") interface DashboardData { tenants: Tenant[] users: User[] audit: AuditLog[] health: OverallHealth | null } const EMPTY: DashboardData = { tenants: [], users: [], audit: [], health: null } export default function HomeRoute() { const session = useSession() const arcadia = useArcadiaClient() const [data, setData] = useState(EMPTY) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [refreshedAt, setRefreshedAt] = useState(null) const refresh = useCallback(async () => { setError(null) setLoading(true) const [tenants, users, audit, health] = await Promise.all([ listTenants(arcadia).catch((err) => { throw err }), listUsers(arcadia), listAuditLogs(arcadia, { limit: 10 }), getHealth(arcadia).catch(() => null), ]).catch((err) => { setError(err instanceof ArcadiaError ? err.message : "Failed to load overview.") return [[], [], [], null] as [Tenant[], User[], AuditLog[], OverallHealth | null] }) setData({ tenants, users, audit, health }) setRefreshedAt(new Date()) setLoading(false) }, [arcadia]) useEffect(() => { if (session) refresh() }, [session, refresh]) const stats = useMemo(() => { const activeTenants = data.tenants.filter((t) => t.status === "active").length const activeUsers = data.users.filter((u) => u.status === "active").length const errorEvents = data.audit.filter( (a) => a.severity === "error" || a.severity === "critical", ).length return { tenants: { total: data.tenants.length, active: activeTenants }, users: { total: data.users.length, active: activeUsers }, audit: { recent: data.audit.length, errors: errorEvents }, health: data.health?.status ?? "unconfigured", } }, [data]) useRegisterContext("overview", stats) return ( Live snapshot of the platform — tenants, users, recent activity, and health. {refreshedAt ? ( <> {" "} Refreshed {refreshedAt.toLocaleTimeString()}. ) : null} } actions={ } /> {error ? ( setError(null)}> {error} ) : null}
0 ? `${stats.audit.errors} error${stats.audit.errors === 1 ? "" : "s"}` : "no errors" } loading={loading} tone={stats.audit.errors > 0 ? "warning" : "default"} />
Recent activity Latest audit events across the platform.
View all →
Subsystems Live probe of each platform subsystem.
) } function StatTile({ to, dataAction, icon: Icon, label, value, sub, loading, tone = "default", }: { to: string dataAction: string icon: React.ComponentType<{ className?: string }> label: string value: number | string sub: string loading: boolean tone?: "default" | "warning" | "error" | "ok" }) { const accent = tone === "error" ? "border-destructive/40 bg-destructive/5" : tone === "warning" ? "border-amber-500/40 bg-amber-500/5" : tone === "ok" ? "border-emerald-500/40 bg-emerald-500/5" : "" return (
{label}
{loading ? ( ) : ( {value} )} {loading ? ( ) : ( {sub} )}
) } function RecentActivity({ logs, loading }: { logs: AuditLog[]; loading: boolean }) { if (loading && logs.length === 0) { return (

Loading…

) } if (logs.length === 0) { return (

No recent events.

) } return (
    {logs.slice(0, 8).map((l) => (
  • {l.action} {l.resource_type} {l.resource_id ? ` · ${l.resource_id.slice(0, 8)}…` : ""} {l.user?.email ?? "system"}
  • ))}
) } function SubsystemList({ health, loading, }: { health: OverallHealth | null loading: boolean }) { if (loading && !health) { return (

Probing…

) } if (!health) { return (

Health endpoint unreachable.

) } return (
    {SUBSYSTEMS.map((sys) => { const sub = health.subsystems[sys] return (
  • {labelFor(sys)} {sub?.message ?? statusLabel(sub?.status ?? "unconfigured")}
  • ) })}
) } function SeverityDot({ severity }: { severity: string }) { const tone = severity === "critical" || severity === "error" ? "bg-destructive" : severity === "warning" ? "bg-amber-500" : "bg-emerald-500" return ( ) } function StatusIcon({ status }: { status: HealthStatus }) { if (status === "ok") return if (status === "degraded") return if (status === "error") return return } function labelFor(sys: HealthSubsystem): string { if (sys === "api") return "API" if (sys === "db") return "Database" return sys } function statusLabel(status: HealthStatus | string): string { if (status === "ok") return "Healthy" if (status === "degraded") return "Degraded" if (status === "error") return "Down" return "Unknown" } function statusTone(status: HealthStatus | string): "default" | "ok" | "warning" | "error" { if (status === "ok") return "ok" if (status === "degraded") return "warning" if (status === "error") return "error" return "default" } function timeAgo(iso: string): string { const t = new Date(iso).getTime() if (Number.isNaN(t)) return "" const diff = Date.now() - t const sec = Math.round(diff / 1000) if (sec < 60) return `${sec}s ago` const min = Math.round(sec / 60) if (min < 60) return `${min}m ago` const hr = Math.round(min / 60) if (hr < 24) return `${hr}h ago` const d = Math.round(hr / 24) return `${d}d ago` }