Files
seminarhof-e2e-mrffg074/docs/design/public.md
2026-07-10 23:07:47 +02:00

132 lines
5.0 KiB
Markdown

# Public Surfaces — UI Design
Audience: prospective clients browsing for dates, returning organisers
checking the calendar, individual guests of a confirmed event filling in
their own dietary info via a tokenised link.
Theme: same Mantine tokens as admin/client/staff (dark surface, red
primary), but **lighter compositions** — more whitespace, larger
typography, hero-style sections. Public is read-only or single-form.
All public pages support an `?embed=1` query param that strips the
shell (header/footer) for WordPress iframe inclusion. Embedded pages
emit `postMessage('resize', { height })` so the WP iframe wrapper can
auto-fit content height.
DE default, EN toggle in the header. Browser locale auto-detected on
first visit; preference persisted.
## 1. Availability calendar — `/availability`
Replaces the public Google Sheet.
- 12 months ahead by default, horizontally scrollable
- Day cells coloured by status (token palette shared with admin):
- `free` — neutral pale
- `enquiry` — soft pink (semi-transparent)
- `reserved` — amber
- `confirmed` — green
- **Privacy:** event name visible on hover/tap **only** for bookings
with `online-ad=true` consent; all other booked days show status
only, never group name. (Q1 lock: "Status + opt-in event names")
- Click a `free` day → "Reserve this date" CTA → opens `/enquiry`
with that date pre-filled
- View toggle: month · quarter · year
- Year-header strip: occupancy %, free-day count
- Embeddable: `/availability?embed=1` returns just the grid
## 2. Events page — `/events`
Lists upcoming events whose organiser opted into public listing
(`online-ad=true`).
- Card per event:
- Cover image (organiser-uploaded, optional)
- Event name
- Dates
- Organiser name
- Short description (`course-info` form field)
- External link to organiser's website (`your-website`)
- Filter chips: This year · Next year · All
- Search (event name / organiser)
- SEO: server-rendered, meta tags, JSON-LD `Event` schema
- Empty state: "No events listed at this moment — please check our
retreat calendar for available dates."
- Cross-link to `/availability` in header
## 3. Booking form — `/enquiry`
The iframe-able binding booking form. Replaces the current WordPress
form long-term; short-term we accept WP webhook posts to the same
backend (Phase 1 of public-entry plan).
### Sections (all sticky on scroll)
1. **Your event** — name, description, website, dates, est. participants
2. **Organiser** — name, email, phone, full legal name, organisation
3. **Billing** — invoice address, payment preference (cash | transfer)
4. **Schedule** — desired arrival / departure times, structured meal
times (Frühstück / Mittag / Abend, validated against venue's
allowed-window config), free-text daily plan
5. **Extras** — cake / 2nd seminar room / early arrival / bedlinen /
massage bench (gross prices)
6. **Setup** — equipment needed (beamer, flipchart, piano, chair count)
7. **Public listing consent** — opt in to show on `/events`
8. **Terms** — AGB acceptance (versioned by event year), privacy
notice acceptance
### Behaviour
- Inline validation; submit failure highlights incomplete sections
- On submit:
- Status = `form_received` (per locked status enum)
- €300 deposit due notice within 14 days
- Auto confirmation email in user's locale (DE/EN)
- Embeddable: `/enquiry?embed=1`, postMessage height resize
## 4. Guest self-form — `/d/:token`
Tokenised link a guest receives from the organiser to fill in their
own dietary info — no account required.
- Single page: name (pre-filled, editable), dietary tag picker,
allergy list, free-text "anything else"
- Token expires when booking is `completed`
- DE/EN locale-aware, auto-detected from browser
- One-time submit with confirmation page; re-openable until cutoff
- Mobile-first (most guests fill from phones)
## 5. Authenticated landing — `/`
- Unauthenticated users → thin welcome page with links to
`/availability`, `/events`, sign-in CTA
- Authenticated users → role-based redirect to their portal
No marketing copy on the platform itself — Sarah keeps the WordPress
site as the brand front door.
## SEO and structured data
- `/availability` — meta description, no indexable detail
- `/events` — JSON-LD `Event` schema per event card; `<title>`
per-card on detail expansion if added later
- `/enquiry``noindex` (form, not content)
- `/d/:token``noindex` (private)
- `/` — minimal `<title>` and `og:` tags
## Components shared with the rest of the platform
- Status pill (theme tokens)
- Day-cell calendar component (admin calendar reuses, with edit
affordances)
- AGB / privacy acceptance component (also used in client portal
on first login)
- DE/EN locale toggle
## Non-goals
- No marketing copy / about / blog — handled by WordPress
- No public booking detail page (events page is summary-only; clients
see full detail in their portal once authenticated)
- No public reviews / testimonials in v1
- No payment processing (deposits are bank transfer, per §6)