173 lines
5.0 KiB
Markdown
173 lines
5.0 KiB
Markdown
# Staff Portal — UI Design
|
||
|
||
Two sub-views: **Kitchen** and **Cleaning**. Same mobile-first shell,
|
||
different content compositions.
|
||
|
||
Audience: kitchen cooks, housekeepers. Read-only. Mobile/tablet first
|
||
(phones over the counter, tablets in the housekeeping cupboard).
|
||
Polled refresh, no websockets in v1.
|
||
|
||
Theme: same Mantine tokens as admin/client (red primary on dark
|
||
surface), but with a simpler layout — large touch targets, generous
|
||
spacing, fewer columns.
|
||
|
||
## Auth and routing
|
||
|
||
- Same `js-auth` flow as admin/client
|
||
- After login, role-based redirect: kitchen → `/staff/kitchen`,
|
||
cleaning → `/staff/cleaning`
|
||
- A staff user can hold both roles (small team); UI offers a switcher
|
||
in the header
|
||
|
||
## Shell
|
||
|
||
- Top bar: venue name · current date · user avatar · role switcher (if
|
||
applicable) · refresh button
|
||
- Body: list / detail
|
||
- No sidebar (mobile-first)
|
||
|
||
---
|
||
|
||
## Kitchen view
|
||
|
||
### 1. Event list (landing)
|
||
|
||
- One card per upcoming event, chronological
|
||
- Card content: dates · group name · headcount · today's meal-count
|
||
badge · "info missing" alert badge if any dietary / headcount
|
||
fields are still pending
|
||
- Filter chips: Today · This week · Upcoming
|
||
- Tap a card → event detail
|
||
|
||
### 2. Event detail
|
||
|
||
The workhorse. Visual-heavy.
|
||
|
||
#### Sticky header
|
||
- Group name · course name · headcount · dates
|
||
- Meal times: Frühstück / Mittagessen / Abendessen (single line)
|
||
|
||
#### Dietary breakdown card (top of body)
|
||
|
||
- `RingProgress` or `DonutChart` showing % per dietary tag (vegan,
|
||
vegetarian, gluten-free, lactose-free, etc.)
|
||
- Counts per slice
|
||
- Same colour tokens reused on the participant list below for visual
|
||
continuity
|
||
|
||
#### Today's meals card
|
||
|
||
- Small KPI tiles per meal: Frühstück / Mittagessen / Abendessen
|
||
- Each tile shows: count for today, delta vs. headcount when
|
||
participants arrive late or leave early ("26 (–2)")
|
||
- Cake tile shows yes/no for today + €3/person/day total when on
|
||
|
||
#### Allergies & specials card
|
||
|
||
- Flat list grouped by allergen (nuts, soy, strict gluten, dairy, etc.)
|
||
- Each row: icon · allergen · count · participant initials
|
||
- Severity tier:
|
||
- ⚠ standard allergy (avoid in dishes)
|
||
- ★ requires fully separate prep (the rare 1% that triggers the
|
||
manual special-diet surcharge)
|
||
|
||
#### Cake days card
|
||
|
||
- Calendar strip (5 days for a 5-night booking)
|
||
- Cake-on days highlighted; €3/person/day shown
|
||
|
||
#### Notes card
|
||
|
||
- Per-booking admin notes filtered to kitchen-relevant only
|
||
(`notes.audience=kitchen`). Personnel notes never appear here.
|
||
|
||
#### Daily plan (free-text)
|
||
|
||
- The free-text portion of the schedule the client submitted
|
||
- Read-only
|
||
|
||
### Data sources
|
||
|
||
All read-side aggregations on existing tables — no new schema:
|
||
|
||
- Dietary breakdown: `SUM(participants) GROUP BY dietary_tag` for the
|
||
booking
|
||
- Today's meals: `participants WHERE booking_id = X AND kind IN
|
||
(overnight, day_guest) AND arrival_date <= today AND departure_date >
|
||
today`
|
||
- Allergies: flat list from `participant_allergies` joined to allergen
|
||
reference table
|
||
- Cake days, meal times: from `bookings.extras` and
|
||
`bookings.meal_times`
|
||
|
||
---
|
||
|
||
## Cleaning view
|
||
|
||
### 1. Event list (landing)
|
||
|
||
- One row per event sorted by changeover date (departure or arrival)
|
||
- Row content: changeover type icon (`departure` / `arrival` /
|
||
`flying`) · date · group name · room count · flying-changeover badge
|
||
- Tap → cleaning detail
|
||
|
||
### 2. Cleaning detail
|
||
|
||
Spatial / temporal, not dietary.
|
||
|
||
#### Sticky header
|
||
- Group · dates · room count · flying-changeover badge if applicable
|
||
("Rooms cleared by 10:00, ready by 17:00")
|
||
|
||
#### Arrivals / departures card
|
||
|
||
- Arrival time and departure time
|
||
- Number of rooms in use
|
||
- Whether the previous group's departure overlaps (flying changeover)
|
||
|
||
#### Room status table (the workhorse)
|
||
|
||
| Room | Type | Beds | Flags | Status |
|
||
|------|------|------|-------|--------|
|
||
| 5 | MBZ | 3 | quiet | clean for arrival 15:00 |
|
||
| 8 | DZ | 2 | shared bath, quiet | clean for arrival 15:00 |
|
||
| 10 | DZ | 2 | dogs allowed | extra deep clean |
|
||
|
||
- Driven by the booking's room assignments
|
||
- Flags surfaced as icons (dogs, wheelchair, allergy-friendly,
|
||
shared bath, double bed 140cm)
|
||
- "Extra deep clean" auto-shown for `dogs_allowed` rooms when occupied
|
||
- Per-room admin note shown inline if present
|
||
|
||
#### Notes card
|
||
|
||
- Per-booking admin notes filtered to cleaning-relevant only
|
||
(`notes.audience=cleaning`)
|
||
|
||
### Data sources
|
||
|
||
All on existing tables:
|
||
|
||
- Room assignments → which rooms are occupied
|
||
- Room flags → from `rooms`
|
||
- Flying changeover → derived from booking start_date == previous
|
||
booking end_date
|
||
|
||
---
|
||
|
||
## Shared shell components
|
||
|
||
- `<StaffEventCard />` — card used in both kitchen and cleaning
|
||
landing lists
|
||
- `<StickyEventHeader />` — same shell, different content props
|
||
- `<NotesCard audience="kitchen|cleaning" />` — filters notes by
|
||
audience tag
|
||
|
||
## Non-goals
|
||
|
||
- No editing anywhere in the staff view (read-only by definition)
|
||
- No real-time updates in v1 — manual refresh button + a "last fetched
|
||
X minutes ago" indicator
|
||
- No WhatsApp integration in v1 — handover §6 explicit
|
||
- No HR features (cook rota assignment is admin-side)
|