/* global React, ReactDOM */ /* ============================================================================ recovery/wow/RecoverySummary.jsx — M2 live-data widget Fetches GET /api/v1/public/recovery/summary · unauthenticated · 30s refresh Exports window.RecoveryLive = { RecoverySummary } ============================================================================ */ (function () { "use strict"; const { useState, useEffect } = React; const API = "/api/v1"; const ACCENT = "#B23A2E"; /* alert red — DR is always high stakes */ function statusColor(incidents_open) { if (incidents_open > 0) return "#B23A2E"; return "#4A7C59"; } function Tile({ label, value, live, alert }) { const color = alert ? "#B23A2E" : ACCENT; return (
{label} {live ? value : "—"}
); } function RecoverySummaryWidget() { const [data, setData] = useState(null); const [live, setLive] = useState(false); const [ts, setTs] = useState(null); useEffect(() => { let cancelled = false; async function poll() { try { const r = await fetch(API + "/public/recovery/summary"); if (!r.ok) { if (!cancelled) { setLive(false); setData(null); } return; } const d = await r.json(); if (!cancelled) { setData(d); setLive(true); setTs(new Date()); } } catch (_) { if (!cancelled) { setLive(false); setData(null); } } } poll(); const id = setInterval(poll, 30000); return () => { cancelled = true; clearInterval(id); }; }, []); const allClear = live && data && data.incidents_open === 0; const borderColor = allClear ? "#4A7C5930" : "#B23A2E44"; const bgColor = allClear ? "#F5FAF7" : "#FFF8F7"; return (
{live ? (allClear ? "● ALL CLEAR" : "⚠ INCIDENTS") : "◌ DEMO"} DR / RECOVERY LIVE DATA {ts && {ts.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", second: "2-digit" })}}
0} /> 0} />
); } window.RecoveryLive = { RecoverySummary: RecoverySummaryWidget }; /* ---- self-mount before #root ------------------------------------------- */ function mountWidget() { const root = document.getElementById("root"); if (!root) return; const el = document.createElement("div"); el.id = "recovery-live-root"; root.before(el); ReactDOM.createRoot(el).render(React.createElement(RecoverySummaryWidget)); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", mountWidget); } else { mountWidget(); } })();