(() => { const menuController = window.WarpBoxUI?.bindMenuBar?.() || { close() { document.querySelectorAll(".menu-item.is-open").forEach((item) => { item.classList.remove("is-open"); item.querySelector(".menu-button")?.setAttribute("aria-expanded", "false"); }); } }; const dataNode = document.getElementById("dashboard-data"); const toast = document.getElementById("toast"); const statusText = document.getElementById("statusText"); const modal = document.querySelector("[data-alert-modal]"); const backdrop = document.querySelector("[data-modal-backdrop]"); const modalTitle = document.getElementById("modalTitle"); const modalMeta = document.getElementById("modalMeta"); const alertCountValue = document.getElementById("alertCountValue"); const alertStatNote = document.getElementById("alertStatNote"); const alertsCard = document.getElementById("alertsCard"); const topAlertChip = document.getElementById("topAlertChip"); const topTaskbar = document.querySelector(".admin-taskbar"); const dashboardData = parseDashboardData(); if (!statusText || !alertsCard || !topAlertChip) return; function parseDashboardData() { try { return JSON.parse(dataNode?.textContent || "{}"); } catch (_) { return {}; } } function showToast(message, type = "info", duration = 2200) { if (window.WarpBoxUI) { window.WarpBoxUI.toast(message, type, { target: toast, duration }); return; } if (!toast) return; toast.textContent = message; toast.classList.add("is-visible"); window.clearTimeout(showToast.timer); showToast.timer = window.setTimeout(() => toast.classList.remove("is-visible"), duration); } function setStatus(message) { statusText.textContent = message; } function openModal(title, meta) { if (!modal || !backdrop || !modalTitle || !modalMeta) return; modalTitle.textContent = title; modalMeta.textContent = meta; modal.classList.add("is-visible"); modal.setAttribute("aria-hidden", "false"); backdrop.classList.add("is-visible"); } function closeModal() { modal?.classList.remove("is-visible"); modal?.setAttribute("aria-hidden", "true"); backdrop?.classList.remove("is-visible"); } function visibleAlertRows() { return Array.from(document.querySelectorAll(".alert-row")).filter((row) => !row.classList.contains("is-dismissed")); } function updateStickyHeader() { topTaskbar?.classList.toggle("is-scrolled", window.scrollY > 4); } function updateAlertSummary() { const rows = visibleAlertRows(); const counts = rows.reduce((acc, row) => { const severity = row.dataset.severity || "low"; acc[severity] = (acc[severity] || 0) + 1; return acc; }, { high: 0, medium: 0, low: 0 }); const score = counts.high * 5 + counts.medium * 2 + counts.low; const total = rows.length; const stateClass = counts.high > 0 || score >= 12 ? "is-danger" : counts.medium >= 2 || score >= 5 ? "is-warning" : total > 0 ? "is-info" : "is-ok"; alertsCard.classList.remove("is-ok", "is-info", "is-warning", "is-danger"); alertsCard.classList.add(stateClass); topAlertChip.classList.remove("is-ok", "is-info", "is-warning", "is-danger"); topAlertChip.classList.add(stateClass); if (alertCountValue) alertCountValue.textContent = String(total); topAlertChip.textContent = total === 0 ? "OK no alerts" : `! ${total} alerts`; if (alertStatNote) { alertStatNote.innerHTML = total === 0 ? 'all clear' : `${counts.high} high${counts.medium} medium${counts.low} low`; } } function scrollToSection(id) { const target = document.getElementById(id); if (!target) return; target.scrollIntoView({ behavior: "smooth", block: "start" }); setStatus(`Focused ${id.replace("-", " ")}`); } function downloadFile(filename, content, type) { const blob = new Blob([content], { type }); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = filename; anchor.click(); URL.revokeObjectURL(url); } function csvEscape(value) { const text = String(value ?? ""); if (!/[",\n]/.test(text)) return text; return `"${text.replaceAll('"', '""')}"`; } function exportBoxesCSV() { const rows = dashboardData.boxes || []; const header = ["id", "status", "files", "size", "created", "expires", "flags"]; const lines = rows.map((box) => [ box.id, box.status_label, `${box.complete_files}/${box.file_count}`, box.total_size_label, box.created_at_label, box.expires_at_label, (box.flags || []).join("|") ].map(csvEscape).join(",")); downloadFile(`warpbox-dashboard-boxes-${new Date().toISOString().replaceAll(":", "-")}.csv`, [header.join(","), ...lines].join("\n"), "text/csv;charset=utf-8"); showToast("Dashboard boxes exported", "success"); } function exportAlertsJSON() { downloadFile(`warpbox-dashboard-alerts-${new Date().toISOString().replaceAll(":", "-")}.json`, JSON.stringify(dashboardData.alerts || [], null, 2), "application/json;charset=utf-8"); showToast("Dashboard alerts exported", "success"); } function exportSnapshot() { downloadFile(`warpbox-dashboard-${new Date().toISOString().replaceAll(":", "-")}.json`, JSON.stringify(dashboardData, null, 2), "application/json;charset=utf-8"); showToast("Dashboard snapshot exported", "success"); } async function postAlertAction(action, ids) { const response = await fetch("/admin/alerts/actions", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action, ids }) }); const payload = await response.json().catch(() => ({})); if (!response.ok) throw new Error(payload.error || "Alert action failed"); return payload; } async function postBoxAction(action, extra = {}) { const response = await fetch("/admin/boxes/actions", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action, ...extra }) }); const payload = await response.json().catch(() => ({})); if (!response.ok) throw new Error(payload.error || "Box action failed"); return payload; } async function closeAlert(row) { const id = row?.dataset.alertId; if (!id) return; await postAlertAction("close", [id]); row.classList.add("is-dismissed"); updateAlertSummary(); showToast(`Closed alert ${row.dataset.alertCode || id}`, "success"); setStatus(`Closed alert ${row.dataset.alertCode || id}`); } async function closeLowAlerts() { const rows = Array.from(document.querySelectorAll('.alert-row[data-severity="low"]')); const ids = rows.map((row) => row.dataset.alertId).filter(Boolean); if (!ids.length) { showToast("No low alerts to close"); return; } await postAlertAction("close", ids); rows.forEach((row) => row.classList.add("is-dismissed")); updateAlertSummary(); showToast(`Closed ${ids.length} low alert(s)`, "success"); setStatus(`Closed ${ids.length} low alert(s)`); } async function cleanupExpiredBoxes() { if (!window.confirm("Clean up expired boxes now? This can delete expired box data.")) return; const payload = await postBoxAction("cleanup_expired"); showToast(payload.message || "Expired cleanup complete", payload.ok ? "success" : "warning", 3200); setStatus(payload.message || "Expired cleanup complete"); window.setTimeout(() => window.location.reload(), 900); } async function runCommand(command) { if (command === "refresh") { window.location.reload(); return; } if (command === "dashboard-snapshot") return exportSnapshot(); if (command === "logout") { window.location.href = "/admin/logout"; return; } if (command === "compact-mode") { document.body.classList.toggle("is-compact"); showToast("Toggled compact density"); return; } if (command === "show-all-boxes") { window.location.href = "/admin/boxes"; return; } if (command === "show-all-alerts") { window.location.href = "/admin/alerts"; return; } if (command === "open-users") { window.location.href = "/admin/users"; return; } if (command === "open-activity") { window.location.href = "/admin/activity"; return; } if (command === "open-settings") { window.location.href = "/admin/settings"; return; } if (command === "export-boxes") return exportBoxesCSV(); if (command === "export-alerts") return exportAlertsJSON(); if (command === "close-low-alerts") return closeLowAlerts(); if (command === "cleanup-expired") return cleanupExpiredBoxes(); if (command === "shortcuts") { showToast("Shortcuts: F5 refresh, Alt+A alerts, Alt+B boxes, Alt+R activity, Esc close menus/modal.", "info", 3600); return; } if (command === "about") { showToast("Live WarpBox admin dashboard backed by alerts, activity, boxes, users, and settings.", "info", 3600); } } document.querySelectorAll("[data-command]").forEach((button) => { button.addEventListener("click", async () => { menuController.close(); try { await runCommand(button.dataset.command); } catch (error) { showToast(error.message || "Command failed", "error", 3600); setStatus(error.message || "Command failed"); } }); }); document.querySelectorAll("[data-scroll-to]").forEach((button) => { button.addEventListener("click", () => { menuController.close(); scrollToSection(button.dataset.scrollTo); }); }); document.querySelectorAll("[data-view-meta]").forEach((button) => { button.addEventListener("click", () => { const row = button.closest(".alert-row"); const title = row?.dataset.alertTitle || "Alert Metadata"; let meta = row?.dataset.alertMeta || "{}"; try { meta = JSON.stringify(JSON.parse(meta), null, 2); } catch (_) { meta = row?.dataset.alertMeta || "{}"; } openModal(`${title} (${row?.dataset.alertCode || "alert"})`, meta); }); }); document.querySelectorAll("[data-close-alert]").forEach((button) => { button.addEventListener("click", async () => { try { await closeAlert(button.closest(".alert-row")); } catch (error) { showToast(error.message || "Could not close alert", "error", 3600); } }); }); document.querySelector("[data-close-modal]")?.addEventListener("click", closeModal); backdrop?.addEventListener("click", closeModal); topAlertChip.addEventListener("click", (event) => { if (document.getElementById("alerts")) { event.preventDefault(); scrollToSection("alerts"); } }); window.addEventListener("scroll", updateStickyHeader, { passive: true }); document.addEventListener("keydown", async (event) => { if (event.key === "Escape") { menuController.close(); closeModal(); } if (event.key === "F5") { event.preventDefault(); await runCommand("refresh"); } if (event.altKey && event.key.toLowerCase() === "a") { event.preventDefault(); scrollToSection("alerts"); } if (event.altKey && event.key.toLowerCase() === "b") { event.preventDefault(); scrollToSection("recent-boxes"); } if (event.altKey && event.key.toLowerCase() === "r") { event.preventDefault(); scrollToSection("recent-activity"); } }); updateAlertSummary(); updateStickyHeader(); })();