From f4f43b100b5723f80966ffd3a26ed903b84f825a Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:19:58 +0330 Subject: [PATCH] Import source: web/src/App Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- web/src/App.tsx | 196 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 web/src/App.tsx diff --git a/web/src/App.tsx b/web/src/App.tsx new file mode 100644 index 0000000..a26ad2c --- /dev/null +++ b/web/src/App.tsx @@ -0,0 +1,196 @@ +import { useEffect, useMemo, useState } from "react"; +import { AnimatePresence, LayoutGroup, motion } from "motion/react"; +import { useMonitor } from "./hooks/useMonitor"; +import { springs, UIProvider, useUI } from "./lib/ui"; +import type { CheckKind } from "./lib/types"; +import { fmtNumber } from "./lib/format"; +import { Header } from "./components/Header"; +import { Boot } from "./components/Boot"; +import { TargetCard } from "./components/TargetCard"; +import { TargetDetail } from "./components/TargetDetail"; +import { OrbitalOverview } from "./components/OrbitalOverview"; +import { RadialDay } from "./components/RadialDay"; +import { IncidentList } from "./components/IncidentList"; +import { PublicView } from "./components/PublicView"; + +const MIN_BOOT_MS = 1700; + +type Filter = "all" | CheckKind; + +function FilterChips({ + targets, + filter, + onChange, +}: { + targets: { type: CheckKind }[]; + filter: Filter; + onChange: (f: Filter) => void; +}) { + const { t, lang, reduced } = useUI(); + const kinds = useMemo(() => { + const present = new Set(targets.map((x) => x.type)); + return (["http", "tls", "tcp", "icmp", "docker"] as CheckKind[]).filter((k) => + present.has(k), + ); + }, [targets]); + + if (kinds.length < 2) return null; + + const chip = (value: Filter, label: string, count: number) => { + const active = filter === value; + return ( + + ); + }; + + return ( +
+ {chip("all", t.all, targets.length)} + {kinds.map((k) => + chip(k, k, targets.filter((x) => x.type === k).length), + )} +
+ ); +} + +function Shell() { + const monitor = useMonitor(); + const { t, mode, reduced } = useUI(); + const [selected, setSelected] = useState( + () => decodeURIComponent(location.hash.slice(1)) || null, + ); + const [filter, setFilter] = useState("all"); + const [bootElapsed, setBootElapsed] = useState(reduced); + + useEffect(() => { + const id = setTimeout(() => setBootElapsed(true), reduced ? 0 : MIN_BOOT_MS); + return () => clearTimeout(id); + }, [reduced]); + + const booted = monitor.ready && bootElapsed; + const selectedTarget = monitor.targets.find((x) => x.id === selected) ?? null; + + // The selected target lives in the URL — deep-linkable, back-button friendly. + const select = (id: string | null) => { + setSelected(id); + history.replaceState(null, "", id ? `#${encodeURIComponent(id)}` : location.pathname); + }; + + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") select(null); + }; + window.addEventListener("keydown", onKey); + return () => window.removeEventListener("keydown", onKey); + }, []); + + const visibleTargets = + filter === "all" + ? monitor.targets + : monitor.targets.filter((x) => x.type === filter); + + return ( +
+ {!booted && } + + {booted && ( + <> +
+
+ + {mode === "public" ? ( + + ) : ( + +
+ {/* hero: orbit + day dial */} +
+ +
+ + +
+
+ + {/* targets grid */} +
+
+

{t.targets}

+
+ +
+
+ + {visibleTargets.map((target, i) => ( + + ))} + +
+
+
+ + + {selectedTarget && ( + i.target_id === selectedTarget.id, + )} + onClose={() => select(null)} + /> + )} + +
+ )} + + )} +
+ ); +} + +export default function App() { + return ( + + + + ); +}