aboutsummaryrefslogtreecommitdiffstats
path: root/static/app.js
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-09 18:12:59 +0100
committerDanilo M. <danix@danix.xyz>2026-11-09 18:12:59 +0100
commit2c098221f4ed09d772df9bece5c71912f1c5e849 (patch)
tree656c77daa1e71bee1ebfc2fbc5a5d5b3b7841757 /static/app.js
parent58b6f3feda3662c2004bdfaa1e7300f14dabd931 (diff)
downloaddeck-it-2c098221f4ed09d772df9bece5c71912f1c5e849.tar.gz
deck-it-2c098221f4ed09d772df9bece5c71912f1c5e849.zip
feat: frontend shell and UDT-themed layout
Diffstat (limited to 'static/app.js')
-rw-r--r--static/app.js39
1 files changed, 39 insertions, 0 deletions
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/<name>.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 = `<h2>${panel.title ?? name}</h2>`;
+ 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();