Import source: web/src/components/PublicView

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:20:05 +03:30
parent c983747ef0
commit 65bec9e950
+98
View File
@@ -0,0 +1,98 @@
import { motion } from "motion/react";
import type { MonitorState } from "../hooks/useMonitor";
import { StatusRing } from "./StatusRing";
import { IncidentList } from "./IncidentList";
import { fmtUptime, pctSign } from "../lib/format";
import { springs, STATE_COLOR, useUI } from "../lib/ui";
/**
* The shareable status page: the same instruments, stripped to their
* quietest form. One headline, one ring per service, the incident log.
*/
export function PublicView({ monitor }: { monitor: MonitorState }) {
const { t, lang, reduced } = useUI();
const { targets, incidents } = monitor;
const anyDown = targets.some((x) => x.state === "down");
const anyDegraded = targets.some((x) => x.state === "degraded");
const allUnknown = targets.every((x) => x.state === "unknown");
const headline = anyDown
? t.outage
: anyDegraded
? t.someDegraded
: allUnknown
? t.pending
: t.allOperational;
const headlineState = anyDown
? "down"
: anyDegraded
? "degraded"
: allUnknown
? "unknown"
: "up";
return (
<main className="max-w-2xl mx-auto px-6 pb-24">
<motion.section
className="text-center pt-16 pb-12"
initial={reduced ? false : { opacity: 0, y: 14 }}
animate={{ opacity: 1, y: 0 }}
transition={reduced ? { duration: 0 } : springs.gentle}
>
<span
className="inline-block size-[9px] rounded-full mb-6"
style={{
background: STATE_COLOR[headlineState],
boxShadow: `0 0 18px ${STATE_COLOR[headlineState]}`,
}}
/>
<h1
className="text-[42px] sm:text-[52px] leading-[1.08] text-paper text-balance"
style={{ fontFamily: "var(--font-display)" }}
>
{headline}
</h1>
</motion.section>
<div className="rule-fade" />
<section className="py-6 flex flex-col">
{targets.map((target, i) => (
<motion.div
key={target.id}
className="flex items-center gap-5 py-3 border-b border-ink-800/60 last:border-0"
initial={reduced ? false : { opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={
reduced ? { duration: 0 } : { ...springs.gentle, delay: 0.1 + i * 0.06 }
}
>
<StatusRing target={target} uptime={target.uptime_24h} size={72} delay={0.1 + i * 0.06} />
<div className="flex-1 min-w-0">
<h3 className="text-[13px] text-paper truncate">{target.name}</h3>
<p className="text-[10px] text-paper-faint mt-0.5" style={{ color: STATE_COLOR[target.state] }}>
{t.state[target.state]}
</p>
</div>
<div className="text-end shrink-0">
<p className="text-[17px] text-paper tabular" style={{ fontFamily: "var(--font-display)" }}>
{target.uptime_24h !== undefined
? `${fmtUptime(lang, target.uptime_24h)}${pctSign(lang)}`
: "—"}
</p>
<p className="microlabel mt-0.5">{t.uptime}</p>
</div>
</motion.div>
))}
</section>
<section className="mt-8">
<div className="microlabel mb-3 flex items-baseline gap-4">
<span>{t.incidents}</span>
<span className="rule-fade flex-1" />
</div>
<IncidentList incidents={incidents.slice(0, 8)} targets={targets} />
</section>
</main>
);
}