Why This Matters

Date selection is the first real commitment a guest makes in the booking flow. Before this step, the guest has only chosen which show they want to see. Once they pick a date, the entire context of the booking is locked: the specific event, its availability, pricing, and the path forward through the remaining steps. Getting this right sets the tone for everything that follows.

How It Works

The date selection screen presents the guest with a calendar view of upcoming show dates, grouped by week. Each date card shows the day, time, and remaining capacity at a glance. The layout is two-column: the left side lists all available events with week dividers; the right side acts as a sticky summary panel that updates as the guest selects different dates. Calendar grouped by week — Events are organized into week buckets using labels like “This Week,” “Next Week,” and short month-day formats for more distant dates. This grouping helps guests quickly scan upcoming options without scanning every individual date. Date cards with time and remaining seats — Each selectable row displays the weekday and month-day in a compact calendar-block style, the show time, and a relative label such as “Today” or “Tomorrow” when applicable. An availability badge indicates capacity status: available, a few seats left, almost full, or sold out. Sold-out state — When an event has no remaining capacity, the card appears dimmed and the Select button is replaced by a sold-out indicator. The row remains visible so guests can see what they are missing and consider other dates. CTA to confirm — Each available event card has a Select button. When chosen, the button changes to a “Selected” state with a checkmark and the gold highlight. The right-side summary panel immediately reflects the choice, showing the full date, the relative label, and the confirmed time.

Key Concepts

Week grouping — Events are bucketed by week using a label key derived from the event date relative to today. Labels include localized “This Week” and “Next Week” for imminent dates, falling back to short month-day strings for future dates beyond the next couple of weeks. Remaining capacity indicator — The AvailabilityBadge component reports seat status in four states: available (plenty of seats), fewLeft (10 or fewer), almostFull (5 or fewer), and soldOut (0 remaining). This drives both the badge color and the card’s interactive state. Sold-out logic — An event is marked sold out when its availability.remaining reaches zero. The card becomes non-interactive and visually de-emphasized, but the row is still rendered so guests can compare other dates. Date and time labels — The dateLabel combines weekday and month-day (e.g., “Friday, May 29”). The timeLabel comes directly from the event data (e.g., “7:00 PM”). The relativeDateLabel provides contextual framing: “Today,” “Tomorrow,” or the weekday name for dates within the current week. Event slug — Each show event carries a slug used in routing and API calls. The slug is derived from the show identifier and event date, and is stored in the selectedEvent context value once a selection is made. See also: Event concept — what a showEvent is and how it relates to a show template. Show concept — the show template that defines the show programme.
Catalog API response shape — Events are fetched from the catalog endpoint and include fields: id, date, time, slug, meetArtistAvailable, and availability metadata (remaining, isSoldOut). The BookingEventCard component receives a flattened array of event card models from the eventWeekGroups selector.Selected event in context — Once a guest selects a date, bookingActions.handleEventSelect(event) stores the full event object in selectedEvent. This value flows through the context and gates visibility of downstream sections like experience selection and guest details.Event grouping — The eventWeekGroups selector in booking-context.tsx iterates over catalog events, computes a weekLabel for each using getEventWeekLabel, groups them into a Map<string, BookingEventWeekGroup>, and returns a sorted array of groups. The component then flattens this array for use in BookingEventCard.