morz-infoboard/docs/superpowers/specs/2026-03-24-frontend-overhaul-design.md
Alwin de268af814 docs: Spec-Review-Korrekturen in Frontend-Overhaul-Design
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 22:38:34 +00:00

8.8 KiB

Frontend Overhaul Design — MORZ Infoboard

Date: 2026-03-24 Status: Approved Scope: All server-rendered HTML templates in server/backend/internal/httpapi/


Summary

Overhaul the frontend of the MORZ Infoboard management UI to be professional, visually polished, and fun to use — while keeping the Go server-side rendering architecture and Bulma CSS framework intact. The MORZ red accent color anchors the brand identity throughout. Tenant and screen-user views are simplified to be idiot-proof; the admin section targets computer-literate users. The playlist editor becomes more interactive with inline editing and no-reload updates.


1. Design Tokens & Global Styles

A shared <style> block (or inline in each template) provides CSS custom properties overriding Bulma defaults:

Token Value Usage
--morz-red #E30613 Primary accent: buttons, active tabs, badges, focus rings
--morz-red-dark #B8000F Hover/active state for red elements
--bg #F7F8FA Page background
--surface #FFFFFF Cards, panels
--shadow 0 1px 4px rgba(0,0,0,.08) Card elevation
--nav-bg #1A1A2E Top navbar background
--radius-card 8px Card border radius
--radius-btn 6px Button border radius

Typography: system-ui, -apple-system, "Segoe UI", sans-serif — no web font load, familiar, fast.

Bulma overrides: Set --bulma-primary to --morz-red so all Bulma primary-colored components (buttons, links, focus) automatically pick up the brand color.


2. Navigation & Layout

Top Navbar (all views)

  • Background: #1A1A2E (charcoal)
  • Left: "MORZ Infoboard" wordmark — "MORZ" in MORZ red, "Infoboard" in white
  • Right: role-dependent links (admin: "Diagnose" link) + logout button (outlined white, small)
  • Mobile: hamburger collapse

Admin layout

  • Max-width container: 960px, generous padding
  • Tab navigation: underline style (red 3px underline on active tab, not Bulma boxed tabs)

Tenant/Screen-user layout

  • Same navbar without Diagnose link
  • Single-focus pages — no tabs where avoidable

Responsive

  • Cards go single-column below 768px
  • Manage page: two-column layout stacks vertically on mobile

3. Login Page

  • Full-height centered layout, off-white background
  • Card: white, box-shadow, border-radius: 8px, 4px top border in MORZ red
  • Above form: "MORZ Infoboard" heading — "MORZ" in red
  • Fields: clean, red focus ring (outline: 2px solid var(--morz-red))
  • Submit button: solid MORZ red, full-width, border-radius: 6px
  • Error: soft red background banner inside the card (no separate notification)
  • Password toggle: eye icon preserved

4. Admin Dashboard

Screens Tab

  • Replaces plain striped table with a responsive card grid (3-col desktop, 2-col tablet, 1-col mobile)
  • Each screen card contains:
    • Name (bold, 1rem)
    • Slug (monospace, muted gray)
    • Orientation badge (pill: "Querformat" / "Hochformat")
    • Online status dot (green/yellow/red)
    • Action buttons: "Playlist" (primary red, small) + "Löschen" (danger outline, small)
  • Header row above grid: "Neuer Bildschirm" button (red) + "Provisionieren" button (outlined)

Users Tab

  • Stays table-based (dense data, admin-appropriate)
  • Better spacing, clear "Neuer Benutzer" button top-right
  • Per-screen user modal: visually cleaned up, same functionality

Modals

  • Existing delete-confirmation and screen-users modals retained, visual polish only
  • Cards use --radius-card, header uses charcoal background

Toast Notifications

  • Existing JS toast system retained
  • Style update: rounded pill (border-radius: 24px), subtle shadow, slides in from top-right with CSS transition

5. Manage / Playlist Editor

The primary daily-use screen. Two-column desktop layout, stacked on mobile.

Left Panel — Playlist (~60% width)

  • Header: screen name + orientation icon, back-link (← Dashboard or ← Admin), screen-switcher dropdown if user has multiple screens
  • Each playlist item is a draggable card:
    • Left: drag handle (⠿ icon, cursor grab)
    • Type icon (from existing typeIcon template func)
    • Title: click to edit inline (contenteditable or small input, saves on blur via fetch POST)
    • Duration: click to edit inline (number input, saves on blur)
    • Enabled toggle: pill switch (green=on, gray=off), instant toggle via fetch POST
    • Validity dates: collapsed by default, expand with a chevron; date inputs shown when expanded
    • Delete button: appears on card hover (right side, red icon)
  • Disabled items: 50% opacity
  • Drag-reorder: SortableJS (already bundled at /static/Sortable.min.js), sends reorder fetch on drop
  • Inline save confirmation: subtle green checkmark icon fades in/out next to the field

Right Panel — Media Library (~40% width)

  • Upload section: collapsed by default, expand with "+ Medium hinzufügen" button; contains drag-and-drop zone (dashed border) + file picker fallback + URL input for web type
  • Asset grid: cards with thumbnail (image/video) or type icon (PDF/web), title, type badge
  • Per-card CTA: "Hinzufügen" (red button) → becomes "✓ Hinzugefügt" (gray, disabled) if already in playlist
  • Delete asset: small trash icon on card hover

Interactions (no page reloads)

  • Toggle enabled → fetch POST /manage/{screenSlug}/items/{itemId} (existing update endpoint)
  • Inline title/duration edit → fetch POST /manage/{screenSlug}/items/{itemId} on blur
  • Reorder → fetch POST /manage/{screenSlug}/reorder
  • Add to playlist → standard form POST (redirect back, which reloads — acceptable)
  • All other destructive actions retain redirect-based flow for safety

6. Tenant Dashboard

  • Replaces two-tab layout with a single-page card-first design
  • Screens section: large, touch-friendly cards — screen icon, name, status dot, single CTA "Playlist bearbeiten →" (red)
  • Media section: below screens, or accessible via a simple toggle — drag-and-drop upload zone (dashed border), asset grid below
  • No dense tables anywhere
  • Status dots live-updated via setInterval fetch to player status API

7. Screen Overview (screen_users with multiple screens)

  • Full-page grid of large tappable screen cards
  • Each card: orientation icon (large), screen name, status dot
  • One tap → direct link to /manage/{slug}
  • No other UI elements — maximum simplicity

8. Provision Wizard

Visual polish only, no functional changes:

  • Step numbers: circles in MORZ red
  • Code blocks: dark terminal style (already present, refine padding/font)
  • Copy buttons: icon-only with tooltip, confirmation checkmark on click
  • Completion card: prominent green checkmark, "Playlist befüllen →" CTA in red

9. Status Indicators

Live status dots used across all views (Tenant dashboard, Screen overview, Admin screen cards):

  • Green: online (last heartbeat < 2 min)
  • Yellow: stale (< 10 min)
  • Red: offline (> 10 min or never seen)
  • Implementation: small setInterval (30s) fetches /api/v1/screens/status (bulk), matches results by screen_id field and updates dot color per screen

Architecture Notes

  • All templates remain in Go const string variables in their respective templates.go files
  • No new build step, no npm, no bundler
  • Bulma CDN link replaced with local /static/bulma.min.css (already present)
  • Bulma variable overrides via CSS custom properties in each template's <style> block
  • SortableJS already available at /static/Sortable.min.js
  • Inline JS kept minimal and vanilla — no new JS libraries introduced
  • CSRF tokens flow unchanged through all form POST operations
  • All existing URL routes and redirect flows preserved exactly

Files to Modify

File Changes
internal/httpapi/manage/templates.go loginTmpl, adminTmpl, manageTmpl, screenOverviewTmpl, provisionTmpl
internal/httpapi/tenant/templates.go tenantDashTmpl
internal/httpapi/manage/ui.go Inline JS fetch handlers for playlist inline editing (no new Go handlers needed — existing endpoints are sufficient)

No database changes. No new API endpoints needed for the visual overhaul (existing update/reorder endpoints cover the inline editing interactions).

Important implementation note: HandleUpdateItemUI currently calls http.Redirect on success. When called via fetch (inline editing), the redirect will be silently followed by the browser and the caller receives the full redirected page — not a clean response. HandleUpdateItemUI must be updated to return 204 No Content when the request is a fetch call (detect via X-Requested-With: fetch header sent by the JS, or simply always return 204 since the manage page JS never needs the redirect). The existing redirect-based HTML form flow for other callers (add item, delete item) is unaffected.