P4 — Seat Map (adresné sezení)
Interaktivní plán sálu, kde si uživatel vybírá konkrétní sedadla. Klíčová obrazovka pro adresné akce — musí být přehledná, rychle reagovat na gesta a jasně komunikovat cenové kategorie a dostupnost.
Content Priority
- Event info header — název akce, datum, čas, venue + sál (kompaktní, 1–2 řádky; v landscape jedna řádka spolu s timerem) App Bar / Top Navigation
- Countdown timer — 20 minut od otevření mapy (ne od prvního výběru). Fáze podle uplynulého času od otevření: 0–15 min normální; 15–18 min žluté varování; 18:00–19:30 červené pulsování; 19:30–20:00 haptika + banner; v 20:00 timeout → X4 Countdown Timer
- Canvas viewport — custom 2D renderer z JSON souřadnic sedadel. iOS: Core Graphics, Android: Canvas. Hit testing: prostorová hash mřížka pro O(1) detekci tapu. Přístupnost: VoiceOver / TalkBack skupiny podle sekce sálu Seat Map Viewport
- Barevné kódování cenových kategorií — min. 4 barvy + šedá pro vyprodáno, jasná vizuální hierarchie Category Seat Legend
- Sekce sálu — přízemí, balkón, lóže vizuálně oddělené čárami a labely Seat Map Viewport
- Legenda — cenové kategorie s barvami a cenami, toggle viditelnost per kategorie Category Seat Legend
- Selected seats chips — strip vybraných sedadel (řada + sedadlo + cena / u lóže jeden chip); tap → deselect. V landscape přístup přes boční swipe Chip / Filter Button
- Bottom bar — počet vybraných sedadel, celková cena, CTA „Pokračovat do košíku". V landscape přemapování na vertikální sidebar CTA Sticky BarPrimary Button
Interakce
| Trigger | Akce | Cíl |
|---|---|---|
| Tap na běžné volné sedadlo | Okamžitý stav „selecting" (pulzující barva) → POST /cart/ticket/add/event | OK: plné „selected", chip, aktualizace ceny. Konflikt: deselect + toast „Sedadlo obsazeno". Detail sedadla v chipu — bez bottom sheetu u prvního tapu |
| Tap na chip (selected) | Deselect sedadla | Sedadlo do původní barvy, chip pryč, přepočet ceny + synchronizace košíku dle API |
| Tap na sedadlo vozíčkáře / jiné speciální | Bottom sheet s informací a potvrzením | Po potvrzení stejný optimistic flow jako u běžného sedadla |
| Tap na lóži | Bottom sheet: „Lóže č. X — N míst — celkem Y Kč — prodává se jako celek" + CTA „Přidat lóži" | Po potvrzení výběr všech míst v lóži, jeden chip „Lóže č. X (N míst)" |
| Pinch-to-zoom | Zoom in/out sálu | Plynulý zoom s min/max limity |
| Double tap | Zoom in na danou oblast | Animovaný zoom 2× |
| Pan (tah jedním prstem) | Posun viewport | Přesouvání po sálu |
| „Pokračovat do košíku" | Přechod na košík | P5 — Košík |
| Uplynulo 15–18 min od otevření mapy | Žluté varování | Vizuální zvýraznění časovače (cca 5–2 min do konce) |
| Uplynulo 18:00–19:30 od otevření | Červené pulsování | Eskalace urgency (cca 2 min–30 s do konce) |
| Uplynulo 19:30–20:00 od otevření | Haptika + banner | Posledních 30 s před timeoutem |
| Timer expiry (0:00) | Timeout error | X4 — Chyba timeout |
| Tap na legendu kategorii | Toggle viditelnost | Sedadla dané kategorie se ztlumí/zobrazí |
| První otevření v zařízení (landscape) | Jednorázový hint | „Otočte telefon pro lepší přehled" (kontext seat mapy) |
Stavy
| Stav | Popis | Vizuální chování |
|---|---|---|
| Loading | Načítání plánu sálu | Centered spinner + „Načítáme plán sálu…" |
| Loaded — žádný výběr | Sál zobrazen, 0 vybraných sedadel | CTA „Pokračovat" disabled, timer už běží (20 min od otevření mapy) |
| Selecting (optimistic) | Čeká na odpověď serveru po tapu | Pulzující zvýraznění sedadla do potvrzení nebo konfliktu |
| Loaded — výběr | 1+ sedadel (nebo celá lóž) vybráno | Timer běží, CTA „Pokračovat do košíku (X Kč)" active |
| Timer — žlutá fáze | 15–18 min od otevření mapy | Žluté varování časovače |
| Timer — červená fáze | 18:00–19:30 od otevření | Červené pulsování |
| Timer — finální fáze | 19:30–20:00 od otevření | Haptika + banner (posledních 30 s) |
| Timer expired | Čas vypršel | Redirect na X4, sedadla uvolněna |
| Max limit reached | Dosažen max. počet vstupenek | Toast „Maximum X vstupenek per objednávku", další tapping ignorován |
| Error | Sál se nepodařilo načíst | Retry CTA |
Edge Cases a Error States
| Scénář | Řešení |
|---|---|
| Sedadlo obsazeno během výběru (konflikt na serveru) | Toast „Sedadlo obsazeno", automatický deselect, sedadlo vizuálně jako obsazené po delta refreshi |
| Velmi velký sál (2000+ sedadel) | Výchozí zoom = celý sál, progressive rendering, lazy draw při zoomu; hash grid pro výkon hit testu |
| Sál má nestandardní tvar (L-tvar, kruhovitý) | Renderer z JSON polygonů/obdélníků, ne rigidní mřížka |
| Uživatel vybere sedadla ve dvou různých sekcích (přízemí + balkón) | Povoleno — chips zobrazují sekci u každého sedadla |
| Countdown timer běží i na pozadí (app minimize) | Timer pokračuje server-side, při návratu sync s API |
| Ztráta připojení během výběru | Offline banner, lokální stav výběru, retry při obnovení |
| Sedadlo pro vozíčkáře | Speciální ikona (♿), bottom sheet s info o bezbariérovosti před potvrzením |
| Lóže (skupina sedadel prodávaných jako celek) | Bottom sheet s cenou za celek a CTA „Přidat lóži"; po potvrzení jeden agregovaný chip |
Mobilní patterny a odlišení od webu
Co děláme zásadně jinak
- Canvas plán sálu — web Colosseum používá textový grid (řady písmen a čísel), MA má vizuální plán vykreslený custom 2D rendererem z JSON (Core Graphics / Android Canvas), ne jako jeden velký SVG dokument
- Pinch-to-zoom — nativní gesto pro zoom, web nemá (jen +/- buttony)
- Optimistic UI + chip jako primární detail — první tap neotevírá bottom sheet; bottom sheet jen u speciálních sedadel a povinně u lóží s potvrzením celku
- Chips pro vybraná sedadla — horizontální scroll v portrait; v landscape dostupné bočním swipem
- Landscape jen na P4 — jediná obrazovka v aplikaci s podporou landscape: kompaktní 1řádková hlavička (titulek + timer), bottom bar → vertikální sidebar, jednorázový hint o otočení telefonu
Co přebíráme z webu
- Barevné kódování cenových kategorií
- Legenda s cenami
Aplikované patterny
- iOS: vlastní
UIView/CALayernebo Core Graphics draw loop, pinch/pan gesture,.sheet()pro lóže/speciální sedadla - Android:
Canvasv Compose / customView,TransformableStatepro zoom/pan,ModalBottomSheetpro lóže/speciální sedadla,SnackbarHostpro toasty
API Data
GET/cashdesk/event/{eventId}GET/cashdesk/event/matrix/{eventId}GET/cashdesk/event/state/{eventId}POST/cart/ticket/add/eventGET/cart| Operace | Endpoint | Trigger | Poznámka |
|---|---|---|---|
| Seat map data | GET /cashdesk/event/{eventId} | Otevření seat mapy | Vrací HallSeatOnline[] s x1,y1,x2,y2 koordináty, barvou (#AARRGGBB), rotací |
| Maticové rozložení | GET /cashdesk/event/matrix/{eventId} | Alternativní view | Maticový layout sálu |
| Refresh stavů (delta) | GET /cashdesk/event/state/{eventId}?since={timestamp} | Polling každé 3 s | Pouze změněná sedadla od since; snížení trafficu oproti full state |
| Přidání adresné vstupenky do košíku | POST /cart/ticket/add/event | Po tapu / potvrzení lóže | Optimistic UI; při konfliktu rollback + toast |
| Přechod do košíku | — (data už na serveru) | Tap „Pokračovat do košíku" | Navigace na P5; případně GET /cart pro jistotu stavu |
| Aktuální košík | GET /cart | Po přidání / návrat na obrazovku | Vrací aktualizovaný košík s validity (countdown) |
V [F1] zvážit upgrade na WebSocket pro push změn obsazenosti v reálném čase místo nebo vedle 3s delta pollu.
Sedadla jsou JSON obdélníky s x1, y1, x2, y2 (souřadnice rohů), color (#AARRGGBB), rotation (stupně clockwise). Sály mají sekce (HallSection) s tvary: Rectangle, Triangle, Quadrilateral, Ellipse. Multi-seats: seat_group_id kladná = dvojsedadlo (vybírat společně), záporná = single. Klient vykresluje Canvas (Core Graphics / Android Canvas) z těchto dat; hit testing přes prostorovou hash mřížku. Přístupnost: seskupení sedadel po sekcích pro screen readery.
Reference — Aktuální web
SCR-WEB-29Textový grid sálu — přízemí + balkón, barevná legenda, zoom buttonySCR-WEB-303 vybraná sedadla na balkónu, celková cena v bottom barReference — CineStar benchmark
SCR-CS-03Grafický plán sálu s barevným kódováním, stepper, bottom sheetSCR-CS-06Legenda sedaček — standardní, VIP, vozíčkáře, lehátko, vybrané, obsazenéSCR-CS-083 vybraná sedadla jako chips, CTA 'Pokračovat' activeSCR-CS-09Warning toast — maximální počet sedadel je 6CineStar má silnou referenci pro seat map v českém kontextu: grafický plán sálu, stepper, chips a legenda. MA navíc řeší 20min timer od otevření mapy, optimistic výběr bez sheetu u běžného sedadla, delta polling a Canvas renderer s výkonovým hit testingem; bottom sheet zůstává u lóží a speciálních míst.





