"use client"; import { useEffect, useState } from "react"; /* Small live mocks for feature rows - data-shaped divs, no images. */ function useReduced() { const [r, setR] = useState(false); useEffect(() => { const mq = window.matchMedia("(prefers-reduced-motion: reduce)"); setR(mq.matches); const fn = (e: MediaQueryListEvent) => setR(e.matches); mq.addEventListener("change", fn); return () => mq.removeEventListener("change", fn); }, []); return r; } function usePing(base: number, spread: number, ms: number) { const [v, setV] = useState(base); const reduced = useReduced(); useEffect(() => { if (reduced) return; const t = setInterval(() => setV(Math.round(base + (Math.random() - 0.4) * spread)), ms); return () => clearInterval(t); }, [base, spread, ms, reduced]); return v; } function HeartbeatStrip({ seed, ms }: { seed: number; ms: number }) { const [bars, setBars] = useState(() => Array.from({ length: 32 }, (_, k) => ((k * seed) % 23 === 0 ? 0 : 1)), ); const reduced = useReduced(); useEffect(() => { if (reduced) return; const t = setInterval( () => setBars((b) => [...b.slice(1), Math.random() > 0.045 ? 1 : 0]), ms, ); return () => clearInterval(t); }, [seed, ms, reduced]); return (
{bars.map((v, k) => ( ))}
); } const MONITORS = [ { name: "gitea.tdvorak.dev", kind: "https · 30s", up: "99.98", base: 38, seed: 3 }, { name: "api.internal", kind: "tcp · 60s", up: "100.00", base: 12, seed: 7 }, { name: "pihole.local", kind: "keyword · 60s", up: "99.62", base: 24, seed: 11 }, ]; function MonitorRow({ m, i }: { m: (typeof MONITORS)[number]; i: number }) { const ping = usePing(m.base, 18, 1700 + i * 300); return (
{m.name}
{m.kind}
{ping} ms
{m.up}%
); } export function MonitorMock() { return (
{MONITORS.map((m, i) => ( ))}
); } const DOMAINS = [ { name: "tdvorak.dev", days: 260, pct: 71, tags: ["porkbun", "cloudflare", "tls 81d"] }, { name: "kan.tdvorak.dev", days: 260, pct: 71, tags: ["porkbun", "cloudflare", "tls 81d"] }, { name: "old-legacy.net", days: 12, pct: 8, tags: ["godaddy", "ns1", "tls 9d"], warn: true }, ]; export function DomainMock() { return (
{DOMAINS.map((d) => (
{d.name}
{d.days}d
{d.tags.map((t) => ( {t} ))}
))}
); } export function SystemMock() { const cpu = usePing(37, 30, 1900); const mem = usePing(61, 6, 2600); const R = 44; const C = 2 * Math.PI * R; return (
{cpu}% cpu
memory {mem}%
disk /data 44%
8 containers load 0.42 · up 14d
); } const ALERTS: { at: string; text: string; kind: "ok" | "down" | "warn" }[] = [ { at: "12:04:11", text: "pihole.local recovered", kind: "ok" }, { at: "12:03:48", text: "pihole.local is down", kind: "down" }, { at: "11:58:02", text: "old-legacy.net expires in 12d", kind: "warn" }, ]; const ALERT_STYLE: Record<(typeof ALERTS)[number]["kind"], string> = { ok: "text-up", down: "text-destructive", warn: "text-down", }; export function StatusBand() { const [i, setI] = useState(0); const reduced = useReduced(); useEffect(() => { if (reduced) return; const t = setInterval(() => setI((v) => (v + 1) % ALERTS.length), 3000); return () => clearInterval(t); }, [reduced]); const a = ALERTS[i]; return (
status page · public /status/lab
All systems operational
{["edge", "api", "media"].map((s) => (
{s} operational
))}
{a.at} {a.text} → slack · ntfy · smtp
); }