diff --git a/src/client/App.tsx b/src/client/App.tsx index 4386257..8407f78 100644 --- a/src/client/App.tsx +++ b/src/client/App.tsx @@ -4,9 +4,11 @@ import { DashboardPage } from "./pages/DashboardPage"; import { LoginPage } from "./pages/LoginPage"; import { MonitorDetailPage } from "./pages/MonitorDetailPage"; import { SettingsPage } from "./pages/SettingsPage"; +import { StatusPage } from "./pages/StatusPage"; function App() { const pathname = usePathname(); + if (pathname === "/") return ; if (pathname === "/login") return ; const monitorMatch = pathname.match(/^\/monitors\/(\d+)\/?$/); const page = monitorMatch diff --git a/src/client/api/status.ts b/src/client/api/status.ts new file mode 100644 index 0000000..f7bea93 --- /dev/null +++ b/src/client/api/status.ts @@ -0,0 +1,26 @@ +import { getJson } from "./http"; + +export type PublicServiceStatus = "up" | "down" | "unknown"; +export type PublicOverallStatus = "operational" | "degraded" | "down"; + +export type PublicService = { + id: number; + name: string; + status: PublicServiceStatus; + lastCheckedAt: string | null; + uptime90d: number | null; + history: Array<{ + day: number; + uptimePct: number | null; + }>; +}; + +export type PublicStatus = { + overall: PublicOverallStatus; + updatedAt: number; + services: PublicService[]; +}; + +export function getStatus(signal?: AbortSignal) { + return getJson("/api/status", { signal }); +} diff --git a/src/client/components/SiteIcon.tsx b/src/client/components/SiteIcon.tsx index 6e448f2..8b3ec3b 100644 --- a/src/client/components/SiteIcon.tsx +++ b/src/client/components/SiteIcon.tsx @@ -3,16 +3,19 @@ import { useState } from "react"; type SiteIconProps = { monitorId: number; + favicon?: "admin" | "public"; }; -export function SiteIcon({ monitorId }: SiteIconProps) { +export function SiteIcon({ monitorId, favicon = "admin" }: SiteIconProps) { const [failed, setFailed] = useState(false); if (failed) return