import { useQuery } from "@tanstack/react-query"; import { http } from "../api/http"; type AppHealth = { ok: true }; type DbHealth = { ok: true; nowISO: string; latencyMs: number }; export default function HealthPage() { const app = useQuery({ queryKey: ["health"], queryFn: () => http("/health"), }); const db = useQuery({ queryKey: ["health", "db"], queryFn: () => http("/health/db"), }); const appStatus = getStatus(app.isLoading, !!app.data?.ok, !!app.error); const dbStatus = getStatus(db.isLoading, !!db.data?.ok, !!db.error); return (

System Health

Quick status for the SkyMoney API and database. Use this when debugging issues or latency.

{/* Status overview */}
{app.error && ( )} } onRetry={!app.isLoading ? () => app.refetch() : undefined} /> {db.error && ( )} } onRetry={!db.isLoading ? () => db.refetch() : undefined} />
{/* Raw data (tiny, for debugging) */}
Debug Useful for logs / screenshots
            API: {app.isLoading ? "Loading…" : JSON.stringify(app.data ?? { ok: false })}{"\n"}
            DB: {db.isLoading ? "Loading…" : JSON.stringify(db.data ?? { ok: false })}
          
); } type Status = "checking" | "up" | "down"; function getStatus( isLoading: boolean, ok: boolean, hasError: boolean, ): Status { if (isLoading) return "checking"; if (ok && !hasError) return "up"; return "down"; } function labelForStatus(status: Status) { if (status === "checking") return "Checking…"; if (status === "up") return "Operational"; return "Unavailable"; } function HealthCard({ label, status, description, details, onRetry, }: { label: string; status: Status; description: string; details: React.ReactNode; onRetry?: () => void; }) { return (
{label}

{description}

{details}
{onRetry && (
)}
); } function StatusPill({ status, className = "", }: { status: Status; className?: string; }) { let text = ""; let tone = ""; switch (status) { case "checking": text = "Checking…"; tone = "bg-amber-500/10 text-amber-100 border border-amber-500/40"; break; case "up": text = "OK"; tone = "bg-emerald-500/10 text-emerald-200 border border-emerald-500/40"; break; case "down": text = "Down"; tone = "bg-red-500/10 text-red-100 border border-red-500/40"; break; } return ( {text} ); } function StatusLine({ label, value }: { label: string; value: string }) { return (
{label} {value}
); }