This UI is split into a small shell page and lazy-loaded tab content.
index.html- Sidebar + tab shell only.
- Each tab pane has a
data-partial="/static/partials/<tab>.html"attribute.
partials/- One HTML file per tab (
dashboard.html,cameras.html,status.html, etc.).
- One HTML file per tab (
js/app.js- Tab router/loader. Loads the partial the first time a tab is opened.
- Calls each tab module's
start()/stop()for lifecycle control.
js/shared.js- Shared helpers (
api,toast, small utilities).
- Shared helpers (
js/tabs/- One JS module per tab. Export
init<tab>Tab(root, shared).
- One JS module per tab. Export
css/app.css- App-specific styles that used to live inline.
- Add a new tab pane in
index.html:<div class="tab-pane fade" id="new-tab" role="tabpanel" data-partial="/static/partials/new-tab.html"></div>
- Create
partials/new-tab.htmlwith the markup. - Create
js/tabs/new-tab.js:export function initNewTab(root, shared) { return { start() {}, stop() {} }; }
- Register the module in
js/app.js(tabModules). - Add the nav link in
index.html.
start()runs when the tab is shown (load data, attach timers, etc.).stop()runs when switching away (clear timers, stop polling).
Keep heavy polling inside start()/stop() so only active tabs do work.