Files
seminarhof-e2e-mrfyfnqt/docs/design/admin.md
2026-07-11 07:59:25 +02:00

11 KiB
Raw Blame History

Admin Portal — UI Design

Audience: Sarah (owner) and Christina (admin assistant). Christina is the heaviest user (booking admin all day). Sarah uses it for oversight, pricing/AGB updates, and high-stakes status decisions.

Theme: shared Mantine tokens with the client portal (dark surface, red primary), but denser components — admin is data-heavy, not card-warm.

Navigation

Sidebar (collapsible to icons-only on smaller screens):

  • Dashboard (default landing)
  • Bookings
  • Calendar
  • Cooks (rota + roster)
  • Organisations (incl. Stammgruppen)
  • Pricing (year-versioned)
  • AGB (versioned PDFs)
  • Venues (multi-tenant — switch venue here)
  • Settings

1. Dashboard (landing)

Static layout for v1. Configurable widget mosaic deferred to v1.5.

┌──────────────────────────────────────────────────────────────┐
│ Action queue                                       [N items] │  full-width
│ Overdue Orga-Mails, missing deposits, missing room plans,    │
│ missing dietary info. Each row → one-click action.           │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────┐  ┌──────────────────────────────┐
│ This week                │  │ Recent client activity       │
│ Arrivals + departures    │  │ Last 48h booking edits       │
│ next 7 days, completeness│  │ across all bookings          │
│ %, flags                 │  │                              │
└──────────────────────────┘  └──────────────────────────────┘
┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐
│ Pipeline /   │  │ Cook rota    │  │ Quick actions        │
│ financial    │  │ status       │  │ + New booking        │
│ KPIs         │  │ unassigned   │  │ + New enquiry        │
└──────────────┘  └──────────────┘  │ + Send Orga-Mail     │
                                    └──────────────────────┘

12-column CSS Grid. Top hero spans 12. Mid row 6+6. Bottom row 4+4+4. Mobile collapses to 1 column.

Widget contracts (v1.5 readiness)

Each section is built as a self-contained React component with a stable key. When the configurable mosaic ships, these become draggable widgets with no contract changes.

2. Bookings list

Table-first. Replaces the Buchungsübersicht spreadsheet.

  • Library: Mantine DataTable or mantine-react-table
  • Columns: Year · Date range · Group / Organisation · Status pill · Persons · Half-house · Orga-Mail sent · Deposit · Final invoice · Notes (truncated)
  • Filters (sidebar drawer): status, year, half-house, has-deposit, has-final-invoice, organisation, missing-info (room plan / dietary / headcount)
  • Sticky header + virtualised rows
  • Bulk actions (with confirmation modals): send Orga-Mail to selected, export DATEV CSV, mark deposit received
  • Full-text search: organisation name + course name
  • Default sort: date ASC, current year first
  • Row click: opens booking detail in same tab

3. Calendar view

Replaces the Belegungsplan spreadsheet.

  • Views: month (default), quarter, year
  • Status colouring mapped to theme tokens:
    • enquiry — pink
    • reserved — amber
    • form_received — yellow
    • deposit_paid — light green
    • confirmed — green
    • completed — grey
    • cancelled — strikethrough red
  • Half-house rendering: day cell splits visually into top/bottom halves when two groups overlap
  • Click cell or booking → open booking detail
  • Drag-and-drop reschedule opens a modal that surfaces the cancellation-policy implications (e.g. "this falls within 12 weeks of arrival — fees may apply")
  • Year header strip: occupancy %, free-day count
  • Filter chips above: org, status (multi-select)

4. Single booking detail

The workhorse. Tabbed organisation.

Sticky header

  • Group name · status pill · dates (large) · headcount · half-house badge
  • Status-transition button (contextual)
  • Quick actions: edit, send Orga-Mail, send reminder, attach invoice, cancel

Main column (left, ~70%) — tabs

  1. Overview
    • Completeness checklist (Orga-Mail sent · deposit · room plan · dietary · headcount · schedule)
    • Key dates timeline
    • Flags (flying changeover · dogs · wheelchair · individual invoicing)
    • Pricing summary (line items + total)
  2. Participants
    • Editable table: name · age · kind (overnight | day_guest) · dietary tags · allergies · room (if overnight)
  3. Room plan — split view, grid as primary editor + live floor-plan visualisation. Both backed by the same room_assignments model.
    • Left — assignment grid: rows = overnight participants; columns = name · age · dietary tags · room (combobox with live capacity counter) · notes. Bulk-select participants → assign to a room. Keyboard-fast (Tab / type-to-search / Enter to commit). Inline validation: overcapacity, conflicting flags (e.g. wheelchair user only assignable to Rooms 1 and 2).
    • Right — floor plan visualisation: SVG overlay on top of grundrisse.pdf, hot-spotted with room rectangles. Each room shows number, capacity dots filled per occupant, flag icons. Live-updates as the grid changes. Click a room → highlights its occupants in the grid. Hover a participant → highlights their room.
    • v1.5 enrichment: click-room-to-assign-selected (spatial click-select pattern matching the rest of admin)
    • Post-MVP: drag a participant card onto a room on the floor plan
  4. Schedule & meals
    • Structured times for Frühstück / Mittagessen / Abendessen (validated against allowed-window config)
    • Free-text daily plan
  5. Extras
    • Booking-time extras (cake, second seminar room, linen, early arrival, etc.)
    • On-site extras logged by staff (sauna, drinks, coffee) with payment_method flag (cash default · invoice)
  6. Invoices
    • Deposit invoice (PDF + DATEV ref + paid status)
    • Final invoice (PDF + DATEV ref + paid status)
    • DATEV line-item export button (CSV/JSON)
  7. Audit log
    • Full change history: who · when · field · before → after

Side column (right, ~30%) — always visible

  • Organiser contact (name · email · phone · billing address · organisation link)
  • Internal notes (Bemerkungen) — markdown, per-booking
  • Recent activity (last 5 changes, link to full audit)
  • Linked enquiry (if any)
  • Assigned KOCH/IN per event day

5. Cook rota grid

Replaces the Küchenplan spreadsheet.

  • Layout: one row per day, one column per cook
  • Left columns (locked / sticky): day-of-month · seminar room occupants (Mandala · Yogaraum) · PAX · KOCH/IN · KOMMENTARE
  • Right columns: one per active staff cook + EXTERN
  • Cells: edit-on-click, code-aware text input with autocomplete from the shift_code enum
  • Shift code enum (DB-backed, not freeform):
    • F — Frühstück
    • M — Mittagessen
    • A — Abendessen
    • S — Spät / extra shift
    • R-K — Reinigung Küche
    • R-HH — Reinigung Haupthaus
    • R-HH-Zi — Reinigung Haupthaus Zimmer
    • GR-K — Grundreinigung Küche
    • nur-A — only dinner
    • off — explicit off
    • Plus optional explicit time (HH:mm) and per-cell free-text note
  • Multiple codes per cell: combine via / (e.g. F/M); UI renders each as a coloured chip
  • Bracket convention ((...)) marking event start/end is auto-rendered by the grid from each booking's start/end dates — not typed
  • Filters above grid: month, cook, event
  • Conflict highlighting: when a cook has overlapping shifts on the same day, cell shows a warning badge

Schema implication

shift_codes
  code   text PK    -- 'F' | 'M' | 'A' | 'S' | 'R-K' | …
  label  text
  color  text       -- theme token

cook_assignments
  id            uuid
  venue_id      uuid → venues
  booking_id    uuid → bookings (nullable for non-event days e.g. GR-K)
  cook_id       uuid → cooks
  date          date
  shift_codes   text[] → shift_codes.code
  explicit_time time
  note          text

6. Auxiliary admin screens (CRUD, low design effort)

  • Organisations — list + detail; Stammgruppe boolean toggle; merge duplicates
  • Pricing — year-versioned editor (one form per year, fields for EZ / DZ / MBZ / day guest / kids 310 / cake / sauna / linen / etc.)
  • AGB — upload PDF per year; list previous versions
  • Venues — switch active venue (multi-tenant); edit venue settings (allowed meal-time windows, default Half House split, etc.)
  • Cooks — roster: name · kind (staff | external_vendor | inactive) · compensation model + amount · notes
  • Settings — current user profile, notifications preferences, language preference, email signature

Styling & component approach

Mantine as the component library. Theme tokens (red primary on dark surface from the client-portal screenshot) shared across all four surfaces — same tokens, surface-specific compositions. Admin uses denser Mantine compositions; client uses warmer card-based ones.

Mantine ecosystem packages used:

  • @mantine/core — components
  • @mantine/dates — date pickers (de locale via dayjs)
  • @mantine/hooks — utilities
  • mantine-react-table (or mantine-datatable) — bookings list virtualisation, filtering, bulk select

No drag-and-drop in MVP. Interactions previously sketched with DnD become click-select-then-target. DnD is a post-MVP enrichment, not a load-bearing primitive — the click pattern works without it.

  • Calendar reschedule — "Reschedule" button → date-picker modal that surfaces cancellation-policy implications inline. Drag-to- reschedule possible later as enrichment.
  • Room plan — split view: assignment grid + live floor-plan SVG. Grid is the primary editor; floor plan visualises live. v1.5 adds click-room-to-assign; post-MVP adds participant drag onto the plan.
  • Cook rota grid — click cell → autocomplete input for shift codes.

Non-goals (defer to v1.5+)

  • Configurable widget mosaic dashboard
  • Real-time websocket updates (polled refresh in v1)
  • Per-user dashboard layout
  • WhatsApp staff notifications (email + in-app only)
  • HR / applicant tracking