# Frontend Overhaul Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Redesign all six server-rendered HTML templates to be professional, polished, and fun to use — with MORZ red accent, system-UI font, and interactive inline editing on the playlist page. **Architecture:** All templates live as Go `const` string variables in two files. Bulma CSS is customized via CSS custom properties. Inline JS handles interactivity; no new libraries, no build step. One small Go handler change makes `HandleUpdateItemUI` return `204` for fetch callers. **Tech Stack:** Go html/template, Bulma CSS (local `/static/bulma.min.css`), SortableJS (local `/static/Sortable.min.js`), vanilla JS ES5+ --- ## Shared CSS Reference Every template gets this ` ``` Shared JS toast helper (include in every template before closing `
`): ```js function showToast(msg, type) { type = type || 'is-success'; var t = document.createElement('div'); t.className = 'morz-toast ' + type; t.innerHTML = msg + ''; document.body.appendChild(t); requestAnimationFrame(function() { t.classList.add('show'); }); setTimeout(function() { t.classList.remove('show'); setTimeout(function() { t.remove(); }, 300); }, 3500); } ``` Shared status-polling helper: ```js function pollScreenStatus(slugToId) { // slugToId: object mapping screen_id -> DOM element id prefix (e.g. 'status-') function update() { fetch('/api/v1/screens/status') .then(function(r) { return r.ok ? r.json() : null; }) .then(function(data) { if (!data || !data.screens) return; data.screens.forEach(function(s) { var el = document.getElementById('status-' + s.screen_id); if (!el) return; var state = s.derived_state || 'unknown'; el.className = 'status-dot ' + (state === 'online' ? 'online' : state === 'degraded' ? 'stale' : 'offline'); el.title = state; }); }).catch(function(){}); } update(); setInterval(update, 30000); } ``` Shared CSRF helper: ```js function getCsrfToken() { var m = document.cookie.match('(?:^|; )morz_csrf=([^;]*)'); return m ? decodeURIComponent(m[1]) : ''; } function injectCSRF() { var token = getCsrfToken(); if (!token) return; document.querySelectorAll('form[method="POST"],form[method="post"]').forEach(function(f) { if (!f.querySelector('input[name="csrf_token"]')) { var inp = document.createElement('input'); inp.type = 'hidden'; inp.name = 'csrf_token'; inp.value = token; f.appendChild(inp); } }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', injectCSRF); else injectCSRF(); ``` --- ## File Map | File | What changes | |---|---| | `server/backend/internal/httpapi/manage/templates.go` | Rewrite all 5 template consts: `loginTmpl`, `provisionTmpl`, `adminTmpl`, `manageTmpl`, `screenOverviewTmpl` | | `server/backend/internal/httpapi/tenant/templates.go` | Rewrite `tenantDashTmpl` | | `server/backend/internal/httpapi/manage/ui.go` | `HandleUpdateItemUI`: return 204 when `X-Requested-With: fetch` header present | --- ## Task 1: HandleUpdateItemUI — return 204 for fetch callers **Files:** - Modify: `server/backend/internal/httpapi/manage/ui.go:781-788` - Test: `server/backend/internal/httpapi/router_test.go` (add test) The handler currently always redirects. Inline editing JS will call it via `fetch`, which needs a 204 back (not a redirect). - [ ] **Step 1: Find the redirect line** In `ui.go`, the last line of `HandleUpdateItemUI` is: ```go http.Redirect(w, r, "/manage/"+screenSlug+"?msg=saved", http.StatusSeeOther) ``` - [ ] **Step 2: Replace with conditional response** Replace that redirect with: ```go if r.Header.Get("X-Requested-With") == "fetch" { w.WriteHeader(http.StatusNoContent) return } http.Redirect(w, r, "/manage/"+screenSlug+"?msg=saved", http.StatusSeeOther) ``` - [ ] **Step 3: Build to verify** ```bash cd server/backend && go build ./... ``` Expected: no errors. - [ ] **Step 4: Commit** ```bash git add server/backend/internal/httpapi/manage/ui.go git commit -m "fix(manage): HandleUpdateItemUI returns 204 for fetch callers" ``` --- ## Task 2: Login page (`loginTmpl`) **Files:** - Modify: `server/backend/internal/httpapi/manage/templates.go` (replace `loginTmpl` const, lines 3–99) - [ ] **Step 1: Replace `loginTmpl`** Replace the entire `loginTmpl` const with: ```go const loginTmpl = `