2d5ec8fc6d
Dark theme matching GOA palette, standalone microsite (no nav). - Landing/login: GOA subhead + big "Suff" wordmark, large tap targets - me page: 2-col 4:3 drink grid, bordered total box, day-grouped history with zebra rows, emoji empty-state - Booking confirmation toast (amber, 5s, then 800ms CSS collapse) - Touch feedback via :active scale, SVG beer favicon - no_pin.html link-buttons styled
65 lines
3.5 KiB
Markdown
65 lines
3.5 KiB
Markdown
# Suff – drink booking tool
|
||
|
||
Self-service drink tab for festival attendees. Lives at `/suff/`. Plain Django, no JS, no CSS yet.
|
||
|
||
## Auth
|
||
|
||
- `User.pin` field (hashed CharField) stores 3-digit PIN, separate from `password`. Lets staff keep a strong password for `/admin/` and use the same username on `/suff/` with just a PIN.
|
||
- `PinBackend` (`gaehsnitz/auth_backends.py`) authenticates by `username` + `pin` via `user.check_pin()`. Default `ModelBackend` stays first in `AUTHENTICATION_BACKENDS` so `/admin/` keeps requiring the strong password.
|
||
- Staff PINs cannot be self-set on `/suff/`. If a name matches an existing user with no PIN, the user lands on `suff/no_pin.html` explaining that an admin must set the PIN via the admin panel — otherwise anyone could claim a staff name and lock out the real owner.
|
||
- Admin convenience: User change page shows PIN status ("gesetzt"/"nicht gesetzt") + "PIN setzen" link → custom admin view `<id>/pin/` with a 3-digit form, calls `user.set_pin()`.
|
||
|
||
## Name flow
|
||
|
||
- Username = `slugify(input)` (e.g. "Flo Hä!" → "flo-ha"). Slug shown back so user can memorize it.
|
||
- POST name → check existence:
|
||
- not found → set new PIN → create user → login
|
||
- found, has PIN → enter PIN → login
|
||
- found, no PIN → `no_pin.html` (ask admin)
|
||
|
||
## Booking
|
||
|
||
- `/suff/me/` shows: greeting (slug), running paid total, full consumption history with timestamps, drink buttons.
|
||
- Each drink = `+1` POST form. Server creates `Consumption(amount=1, day=current_weekday, for_free=False, created_at=auto)`.
|
||
- No undo, no delete, no edit. No special bartender role.
|
||
- History sorted newest-first, `created_at` shown as `Do 18:42` etc.
|
||
|
||
## Time gating (Berlin tz)
|
||
|
||
- Phases: `before` / `booking` / `readonly` / `closed`.
|
||
- Booking allowed Thu 2026-06-11 00:00 → Sun 2026-06-14 23:59.
|
||
- Read-only until Sun 2026-06-21 23:59.
|
||
- After: every `/suff/` URL returns 404.
|
||
- Local dev: `settings.PRODUCTION=False` forces `booking` phase always.
|
||
|
||
## Files
|
||
|
||
- `gaehsnitz/auth_backends.py` — `PinBackend`
|
||
- `gaehsnitz/suff.py` — views + phase logic
|
||
- `gaehsnitz/suff_urls.py` — routes
|
||
- `gaehsnitz/admin.py` — `SetPinForm` + `set_pin_view`
|
||
- `gaehsnitz/templates/suff/{base,name,pin,no_pin,me}.html`
|
||
- `gaehsnitz/templates/admin/gaehsnitz/user/set_pin.html`
|
||
- `gaehsnitz/static/suff/{style.css,favicon.svg}`
|
||
- `gaehsnitz/migrations/0003_consumption_created_at_user_pin.py`
|
||
- Edits: `gaehsnitzproject/settings.py`, `gaehsnitzproject/urls.py`, `gaehsnitz/models.py`
|
||
|
||
## Frontend
|
||
|
||
Mobile-first styled. Dark theme matching GOA palette (`#161616` bg, `#EE9933`/`#FFCC77` amber accents, `#885522` brown borders). Standalone microsite — no nav to main GOA page.
|
||
|
||
- Landing/login: GOA subhead + big "Suff" wordmark, `name` and `pin` forms with stacked label/input, large tap targets
|
||
- `me` page: 2-col drink button grid (4:3 aspect), stacked +1 / name / price; bordered total box; day-grouped history with zebra rows; emoji empty-state
|
||
- Booking confirmation: amber toast, 5s display, then 800ms collapse animation (pure CSS, no JS)
|
||
- `:active` scale(0.96) feedback on buttons + link-buttons
|
||
- `no_pin.html` link-buttons styled (primary + secondary)
|
||
- SVG favicon (🍺)
|
||
|
||
## Further ideas
|
||
|
||
- Color-code drink buttons (per-drink accent border or bg — Bier amber, Wasser blue, etc.) for fast visual recognition in dim light
|
||
- Drink icons/emoji per type
|
||
- Style phase pages (`before` / `closed` if non-404)
|
||
- PWA manifest for add-to-homescreen
|
||
- Donation/free-drink flow if needed (currently admin-only via `for_free`)
|