From 6cedb053f88945674061e737efc263b7bb4532d2 Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:20:12 +0330 Subject: [PATCH] Import source: web/src/components/TargetDetail Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- web/src/components/TargetDetail.tsx | 207 ++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 web/src/components/TargetDetail.tsx diff --git a/web/src/components/TargetDetail.tsx b/web/src/components/TargetDetail.tsx new file mode 100644 index 0000000..6a1a637 --- /dev/null +++ b/web/src/components/TargetDetail.tsx @@ -0,0 +1,207 @@ +import { motion } from "motion/react"; +import type { Bucket, Incident, LiveTarget } from "../lib/types"; +import { StatusRing } from "./StatusRing"; +import { Sparkline } from "./Sparkline"; +import { RadialDay } from "./RadialDay"; +import { IncidentList } from "./IncidentList"; +import { + fmtDate, + fmtInterval, + fmtLatency, + fmtNumber, + fmtUptime, + pctSign, +} from "../lib/format"; +import { springs, STATE_COLOR, useUI } from "../lib/ui"; + +interface TargetDetailProps { + target: LiveTarget; + buckets: Bucket[]; + incidents: Incident[]; + onClose: () => void; +} + +function Stat({ label, value, accent }: { label: string; value: string; accent?: string }) { + return ( +
+ {label} + + {value} + +
+ ); +} + +/** + * The expanded view: shares its layout with the grid card, so the ring + * physically travels from the grid into the panel. + */ +export function TargetDetail({ target, buckets, incidents, onClose }: TargetDetailProps) { + const { t, lang, window, reduced } = useUI(); + const uptime = window === "7d" ? target.uptime_7d : target.uptime_24h; + + return ( + + {/* veil */} +
+ + + {/* state edge */} + + + + +
+ {/* top: ring + identity */} +
+ + + + +
+ + {target.name} + +

+ {target.type === "http" ? ( + + {target.endpoint} ↗ + + ) : ( + target.endpoint + )} +

+

+ ● {t.state[target.state]} + {target.fails > 0 && target.state !== "down" && ( + · {fmtNumber(lang, target.fails)} {t.failed} + )} +

+ + + + + + + {target.uptime_30d !== undefined ? ( + + ) : ( + + )} + {target.cert_days !== undefined && ( + + )} + +
+
+ + {/* middle: sparkline + personal day dial */} + +
+
+ {t.latency} + +
+ +
+
+ +
+
+ + {/* bottom: incidents */} + +
+ {t.recentIncidents} + +
+ +
+
+
+ + ); +}