From 2c098221f4ed09d772df9bece5c71912f1c5e849 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 9 Nov 2026 18:12:59 +0100 Subject: feat: frontend shell and UDT-themed layout --- static/app.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 static/app.js (limited to 'static/app.js') diff --git a/static/app.js b/static/app.js new file mode 100644 index 0000000..7a9ff40 --- /dev/null +++ b/static/app.js @@ -0,0 +1,39 @@ +// The shell: discover modules, mount each panel, poll its state. +// A module is static/modules/.js exporting default {title, interval, +// mount(el), update(state, el)}. A missing or broken panel is skipped. + +const grid = document.getElementById("grid"); + +async function mountModule(name) { + let panel; + try { + panel = (await import(`./modules/${name}.js`)).default; + } catch { + return; + } + const el = document.createElement("section"); + el.className = "panel"; + el.dataset.module = name; + el.innerHTML = `

${panel.title ?? name}

`; + grid.append(el); + panel.mount?.(el); + + const poll = async () => { + try { + const r = await fetch(`/api/${name}`); + if (r.ok) panel.update?.(await r.json(), el); + } catch { + // keep the last state; the next tick retries + } + }; + await poll(); + setInterval(poll, (panel.interval ?? 1) * 1000); +} + +async function boot() { + const r = await fetch("/api/modules"); + if (!r.ok) return; + for (const { name } of await r.json()) await mountModule(name); +} + +boot(); -- cgit v1.2.3