/* 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();
}
})();