Skip to content

Festival phase: Live — now / next #138

Description

@chiptus

Parent

Epic #126 — Festival phases. PRD: docs/prd/festival-phases/2-live-phase.md.

What to build

When the edition is Live (useFestivalPhase() === "live", from #136), adapt the experience for someone standing in the field: they want what's on now and next, not a voting list. Live is an emphasis shift, not a different app — voting stays fully available and nothing from Planning is removed.

  • Land on the Schedule tab by default — extend the phase-driven default-tab mechanism from Festival phase: Pre-Schedule & Planning experience #137 so Live → Schedule. No tabs added or hidden.
  • New pure now/next classifier(sets, now) → classification (now-playing / next / later-past), festival-tz, now injected. Mirrors the pure/injectable shape of getFestivalPhase. Reuses set timing already loaded for the Schedule and the timeUtils festival-tz helpers.
    • now-playing: time_start <= now < time_end (exactly at time_end ⇒ no longer now-playing).
    • next: the nearest upcoming set(s) after now; ties and multi-stage concurrency handled deterministically.
  • Schedule-tab "Now / Next" section — when Live, lead with a section built from the classifier, above the existing full views (Timeline/List, or Multi-mode Schedule tab UX for days/stages reveal levels #47's progressive views below full). Now-playing marked as current; the next block shows immediately upcoming sets. Reuse the existing masked set row (MobileSetCard/set-row) so voting, set-detail links, and self-hiding stage/time badges come for free.
  • Compact Live banner — reuse the shared phase-banner component with Live copy ("the festival is on"). One line.
  • Sub-full reveal fallback — "Now / Next" needs time_start/time_end (only present at reveal level full). If Live is reached below full, skip the Now/Next section and show whatever the reveal level renders plus the Live banner. Never fabricate or leak hidden times.
  • No live ticker — computed per render/navigation; no background timer.

Acceptance criteria

  • When the edition is Live, the app lands on the Schedule tab by default.
  • The now/next classifier marks a set now-playing for now in [time_start, time_end) and not at exactly time_end; selects nearest upcoming set(s) as "next"; handles ties / multi-stage concurrency deterministically; excludes missing/masked-time sets without error.
  • Classifier is a standalone pure function unit-tested with now injected in a non-UTC festival timezone (incl. a viewer-vs-festival calendar-day mismatch); no clock/DOM/React mocking.
  • The Schedule tab, when Live, leads with a Now / Next section above the full schedule, using the shared masked set row; the full schedule remains reachable.
  • Compact Live banner shown, reusing the shared phase-banner component.
  • Below reveal level full, the Now/Next section is skipped gracefully (banner still shown, no leaked times).

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions