g1t/apps/web/app/lib/status.ts

44 lines1,519 bytesCodeBlame
1/**
2 * g1t's status lives at status.g1t.sh (apps/status), a Worker of its own
3 * that stays up when the site does not. The site only links to it, and
4 * reads its JSON for the dot in the account menu and the footer.
5 */
6import type { StatusOverallState, StatusReport } from "@g1t/contracts";
7
8export type { StatusOverallState as OverallState, StatusReport };
9
10/** The status page. */
11export const STATUS_URL = "https://status.g1t.sh";
12/** Its report, as JSON, readable from any origin. */
13export const STATUS_JSON_URL = `${STATUS_URL}/status.json`;
14
15/** Two or three words for the whole, when the report has none. */
16export const STATUS_WORDS: Record<StatusOverallState, string> = {
17 up: "All systems normal",
18 degraded: "Partial outage",
19 down: "Major outage",
20 maintenance: "Under maintenance",
21 unknown: "Status unknown",
22};
23
24/** The short line for the whole: the report's own title, else words for its state. */
25export function statusTitle(report: Pick<StatusReport, "overall"> | null | undefined): string | null {
26 if (!report?.overall) return null;
27 return report.overall.title || STATUS_WORDS[report.overall.state] || null;
28}
29
30/** The dot's colour for a state, as a Tailwind background class. */
31export function dotClass(state: string | null | undefined): string {
32 switch (state) {
33 case "up":
34 return "bg-accent";
35 case "degraded":
36 return "bg-warn";
37 case "down":
38 return "bg-danger";
39 case "maintenance":
40 return "bg-info";
41 default:
42 return "bg-faint";
43 }
44}