(function () { "use strict"; const qs = (selector, root = document) => root.querySelector(selector); const qsa = (selector, root = document) => [...root.querySelectorAll(selector)]; const toastRegion = qs("[data-toast-region]"); let lastFocused = null; function toast(message) { if (!toastRegion) return; const item = document.createElement("div"); item.className = "toast"; item.setAttribute("role", "status"); item.textContent = message; toastRegion.appendChild(item); window.setTimeout(() => item.remove(), 3600); } function setView(name) { qsa("[data-view]").forEach((view) => { const active = view.dataset.view === name; view.classList.toggle("active", active); view.hidden = !active; }); qsa("[data-view-target]").forEach((button) => { const active = button.dataset.viewTarget === name; button.classList.toggle("active", active); if (active) button.setAttribute("aria-current", "page"); else button.removeAttribute("aria-current"); }); const selected = qs(`[data-view-target="${name}"]`); const title = selected?.dataset.title || selected?.textContent.trim(); const pageName = qs("[data-page-name]"); if (pageName && title) pageName.textContent = title; qs("#main-content")?.focus({ preventScroll: true }); qs("[data-sidebar]")?.classList.remove("open"); qs("[data-mobile-menu]")?.setAttribute("aria-expanded", "false"); } qsa("[data-view-target]").forEach((button) => { button.addEventListener("click", () => setView(button.dataset.viewTarget)); }); qs("[data-mobile-menu]")?.addEventListener("click", () => { const sidebar = qs("[data-sidebar]"); const open = sidebar.classList.toggle("open"); qs("[data-mobile-menu]").setAttribute("aria-expanded", String(open)); }); function openModal(id, trigger) { const backdrop = qs(`#${id}`); if (!backdrop) return; lastFocused = trigger || document.activeElement; backdrop.classList.add("open"); backdrop.setAttribute("aria-hidden", "false"); document.body.style.overflow = "hidden"; qs("input, select, textarea, button", qs(".modal", backdrop))?.focus(); } function closeModal(backdrop) { if (!backdrop) return; backdrop.classList.remove("open"); backdrop.setAttribute("aria-hidden", "true"); document.body.style.overflow = ""; lastFocused?.focus(); } qsa("[data-open-modal]").forEach((trigger) => { trigger.addEventListener("click", () => openModal(trigger.dataset.openModal, trigger)); }); qsa("[data-close-modal]").forEach((trigger) => { trigger.addEventListener("click", () => closeModal(trigger.closest(".modal-backdrop"))); }); qsa(".modal-backdrop").forEach((backdrop) => { backdrop.addEventListener("mousedown", (event) => { if (event.target === backdrop) closeModal(backdrop); }); }); document.addEventListener("keydown", (event) => { if (event.key === "Escape") closeModal(qs(".modal-backdrop.open")); }); qsa("[role='tab'][data-tab-target]").forEach((tab) => { tab.addEventListener("click", () => { const group = tab.closest("[data-tabs]"); qsa("[role='tab']", group).forEach((item) => { item.setAttribute("aria-selected", String(item === tab)); item.tabIndex = item === tab ? 0 : -1; }); qsa(".tab-panel", group.parentElement).forEach((panel) => { const active = panel.id === tab.dataset.tabTarget; panel.classList.toggle("active", active); panel.hidden = !active; }); }); }); qsa("[data-filter-input]").forEach((input) => { input.addEventListener("input", () => { const table = qs(input.dataset.filterInput); const query = input.value.trim().toLocaleLowerCase("zh-CN"); qsa("tbody tr", table).forEach((row) => { row.hidden = query && !row.textContent.toLocaleLowerCase("zh-CN").includes(query); }); }); }); qsa("[data-toast]").forEach((button) => { button.addEventListener("click", () => toast(button.dataset.toast)); }); const addDevice = qs("[data-action='add-device']"); addDevice?.addEventListener("click", () => { const name = qs("#device-name")?.value.trim() || "新摄像头"; const address = qs("#device-address")?.value.trim() || "192.168.10.88"; const tbody = qs("#device-table tbody"); if (tbody) { const row = document.createElement("tr"); row.innerHTML = `