restaurant/docs/cms.md
Padreug 42746d7321 fix(cms): KDS card text legible on dark mode
The age-escalation highlights (bg-amber-1 / bg-orange-1 /
bg-red-1) are very pale Quasar shades. On LNbits dark mode the
q-card inherits a near-white text color from the theme — paired
with the pale background that's white-on-cream, which is what
the user reported: the '1x Coffee' on a ready-card was barely
visible.

Pin an explicit text-grey-9 alongside each pale bg so dark text
on light background renders in both themes. The 'no highlight'
branch returns '' unchanged, so non-aged orders still use the
q-card's theme-aware default text color.
2026-05-11 19:18:33 +02:00

4.5 KiB
Raw Permalink Blame History

CMS

The operator-facing console — what the restaurant owner sees when they enable the extension. Lives under /restaurant/... and uses LNbits' built-in Vue 3.5 + Quasar 2.18 UMD runtime: no build step, no bundler, just Jinja templates including a per-page JS file.

Pages

All pages extend base.html (provided by LNbits core) and require a logged-in user (check_user_exists).

Path Template Script Purpose
/restaurant/ restaurant/index.html static/js/index.js Restaurant list / dashboard
/restaurant/{slug} restaurant/menu.html static/js/menu.js menu-tree builder (q-tree)
/restaurant/{slug}/orders restaurant/orders.html static/js/orders.js Order monitor
/restaurant/{slug}/kds restaurant/kds.html static/js/kds.js Kitchen Display
/restaurant/{slug}/settings restaurant/settings.html static/js/settings.js Restaurant + extension settings

Conventions

  • {% extends "base.html" %} and {% from "macros.jinja" import window_vars with context %}.
  • Page content goes in {% block page %}. Scripts in {% block scripts %}, after {{ window_vars(user) }}.
  • The page JS sets window.app = Vue.createApp({mixins: [windowMixin], data, methods, created}). LNbits' init-app.js runs after the extension scripts and finishes the mount with app.use(Quasar) + app.mount('#vue')don't call .mount() yourself.
  • Bootstrap data is injected via <script>window.X = {{ thing | tojson | safe }}</script> between the macro and the per-page script.
  • The shared REST client is static/js/api.js, exposing window.RestaurantAPI (one method per resource).

Menu builder (q-tree)

The menu page uses Quasar's q-tree directly off the hydrated tree returned by GET /api/v1/restaurants/{id}/menu. Three-pane layout:

+--------------------+----------------+----------------------------+
| sidebar nav        | q-tree         | Items panel                |
| (orders / KDS /    |  with inline   |  (filtered by selected     |
|  settings links)   |  edit buttons  |   tree node)               |
+--------------------+----------------+----------------------------+

Custom default-header slot renders:

  • node name + item-count badge + child-count hint
  • inline buttons: add (disabled at depth 3), edit, drive_file_move, delete (with cascade prompt)

Add-root button sits above the tree (+ New top-level).

The Move dialog uses a flat-indented q-select of all nodes, filtered to exclude the moved node + its descendants and any depth-3 candidate. (The server enforces both checks too — see menu-tree.)

Drag-drop reorder is v2; v1 uses the explicit Move dialog.

Item dialog

The item dialog includes a flat-indented q-select for node_id, populated by walking the tree with em-space indentation per depth level. An item can land on any node, not just leaves.

Modifier groups + modifiers live in a separate dialog (a child of the item dialog) with the chooseOne / chooseMany / required / optional semantics from data-model.

Order monitor + KDS

Both use the same data source (GET /restaurants/{id}/orders) filtered by status. The KDS view escalates color by age (>5min orange, >15min red) and offers one-tap state transitions.

Today the monitor + KDS poll every 58 s. SSE / Nostr push is on the roadmap.

Dark-mode color discipline

Quasar's pale bg-{color}-1 utility classes (e.g. bg-orange-1, bg-red-1, bg-amber-1) pair fine with the default light theme but render white-on-cream under LNbits' dark theme — the q-card otherwise inherits the body's light text color. The KDS cards pin a dark text class alongside every pale background so the card stays legible regardless of theme:

if (order.status === 'ready')  return 'bg-amber-1 text-grey-9'
if (ageSec > 900)              return 'bg-red-1 text-grey-9'
if (ageSec > 300)              return 'bg-orange-1 text-grey-9'
return ''   // theme-default branch keeps q-card's own text color

Any future surface that ages / escalates with bg-{color}-1 must do the same. Never assume a pale background "just works" on dark theme.

Settings

settings.html saves restaurant fields via PUT /restaurants/{id} and (for LNbits admins) extension-wide toggles via PUT /settings. NIP-17 orders toggle is currently disabled because the unwrap step is stubbed — see nostr-layer.

See also