Přeskočit na hlavní obsah

P4 — Seat Map (adresné sezení)

Screen IDP4
Typ Primární
FázeMVP
Účel obrazovky

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

  1. 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
  2. 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
  3. 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
  4. Barevné kódování cenových kategorií — min. 4 barvy + šedá pro vyprodáno, jasná vizuální hierarchie Category Seat Legend
  5. Sekce sálu — přízemí, balkón, lóže vizuálně oddělené čárami a labely Seat Map Viewport
  6. Legenda — cenové kategorie s barvami a cenami, toggle viditelnost per kategorie Category Seat Legend
  7. 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
  8. 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

TriggerAkceCíl
Tap na běžné volné sedadloOkamžitý stav „selecting" (pulzující barva) → POST /cart/ticket/add/eventOK: 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 sedadlaSedadlo 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ímPo potvrzení stejný optimistic flow jako u běžného sedadla
Tap na lóžiBottom 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-zoomZoom in/out sáluPlynulý zoom s min/max limity
Double tapZoom in na danou oblastAnimovaný zoom 2×
Pan (tah jedním prstem)Posun viewportPřesouvání po sálu
„Pokračovat do košíku"Přechod na košíkP5 — 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 + bannerPosledních 30 s před timeoutem
Timer expiry (0:00)Timeout errorX4 — Chyba timeout
Tap na legendu kategoriiToggle viditelnostSedadla 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

StavPopisVizuální chování
LoadingNačítání plánu sáluCentered spinner + „Načítáme plán sálu…"
Loaded — žádný výběrSál zobrazen, 0 vybraných sedadelCTA „Pokračovat" disabled, timer už běží (20 min od otevření mapy)
Selecting (optimistic)Čeká na odpověď serveru po tapuPulzující zvýraznění sedadla do potvrzení nebo konfliktu
Loaded — výběr1+ sedadel (nebo celá lóž) vybránoTimer běží, CTA „Pokračovat do košíku (X Kč)" active
Timer — žlutá fáze15–18 min od otevření mapyŽluté varování časovače
Timer — červená fáze18:00–19:30 od otevřeníČervené pulsování
Timer — finální fáze19:30–20:00 od otevřeníHaptika + banner (posledních 30 s)
Timer expiredČas vypršelRedirect na X4, sedadla uvolněna
Max limit reachedDosažen max. počet vstupenekToast „Maximum X vstupenek per objednávku", další tapping ignorován
ErrorSál se nepodařilo načístRetry 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ěruOffline banner, lokální stav výběru, retry při obnovení
Sedadlo pro vozíčkářeSpeciá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 / CALayer nebo Core Graphics draw loop, pinch/pan gesture, .sheet() pro lóže/speciální sedadla
  • Android: Canvas v Compose / custom View, TransformableState pro zoom/pan, ModalBottomSheet pro lóže/speciální sedadla, SnackbarHost pro toasty

API Data

GET/cashdesk/event/{eventId}GET/cashdesk/event/matrix/{eventId}GET/cashdesk/event/state/{eventId}POST/cart/ticket/add/eventGET/cart
OperaceEndpointTriggerPoznámka
Seat map dataGET /cashdesk/event/{eventId}Otevření seat mapyVrací HallSeatOnline[] s x1,y1,x2,y2 koordináty, barvou (#AARRGGBB), rotací
Maticové rozloženíGET /cashdesk/event/matrix/{eventId}Alternativní viewMaticový layout sálu
Refresh stavů (delta)GET /cashdesk/event/state/{eventId}?since={timestamp}Polling každé 3 sPouze změněná sedadla od since; snížení trafficu oproti full state
Přidání adresné vstupenky do košíkuPOST /cart/ticket/add/eventPo tapu / potvrzení lóžeOptimistic 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šíkGET /cartPo přidání / návrat na obrazovkuVrací aktualizovaný košík s validity (countdown)
[F1] Rozšíření synchronizace

V [F1] zvážit upgrade na WebSocket pro push změn obsazenosti v reálném čase místo nebo vedle 3s delta pollu.

CoreAPI poznatek — Seat map formát

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-29: Textový grid sálu — přízemí + balkón, barevná legenda, zoom buttony
Web ColosseumSCR-WEB-29Textový grid sálu — přízemí + balkón, barevná legenda, zoom buttony
SCR-WEB-30: 3 vybraná sedadla na balkónu, celková cena v bottom bar
Web ColosseumSCR-WEB-303 vybraná sedadla na balkónu, celková cena v bottom bar

Reference — CineStar benchmark

SCR-CS-03: Grafický plán sálu s barevným kódováním, stepper, bottom sheet
CineStar benchmarkSCR-CS-03Grafický plán sálu s barevným kódováním, stepper, bottom sheet
SCR-CS-06: Legenda sedaček — standardní, VIP, vozíčkáře, lehátko, vybrané, obsazené
CineStar benchmarkSCR-CS-06Legenda sedaček — standardní, VIP, vozíčkáře, lehátko, vybrané, obsazené
SCR-CS-08: 3 vybraná sedadla jako chips, CTA 'Pokračovat' active
CineStar benchmarkSCR-CS-083 vybraná sedadla jako chips, CTA 'Pokračovat' active
SCR-CS-09: Warning toast — maximální počet sedadel je 6
CineStar benchmarkSCR-CS-09Warning toast — maximální počet sedadel je 6
Inspirace z CineStar

CineStar 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.