Skip to content

Event Series Frontend

Use this page when changing Event Series or Edition routes, pages, forms, workflows, media state, navigation, or query ownership. The frontend reflects the bounded domain described in Event Series Architecture; it must not manufacture schedules, locations, or attendance by aggregating incomplete previews.

The public page family contains:

  • A paginated Event Series Index at /[locale]/event-series.
  • Series Details at /[locale]/event-series/[eventSeriesID].
  • Nested Edition Details at /[locale]/event-series/[eventSeriesID]/editions/[eventSeriesEditionID].

Protected authoring routes provide Add/Edit Series plus nested Add/Edit Edition jobs. There is no standalone Edition Index. Events retain their own canonical routes and Index even when they belong to a Series or Edition.

Server route wrappers own locale normalization, public-ID and slug canonicalization, authorization, prefetch, hydration, and route-level not-found/error behavior. Client components own interaction and presentation over strict DTOs. Repeated query parameters survive canonical redirects.

The Index follows the established collection-page shell and uses a dedicated Event Series Card. The card preserves the Event-card silhouette while presenting Series category, continuity, structure-specific counts, and profile media.

Series and Edition Details reuse the mature detail-page composition:

  • Top-aligned profile/gallery showcase and header content.
  • Neutral-backed section headings with counts beside relationship titles.
  • Ordinary links as compact destination-icon controls; ticket destinations remain a structured section.
  • Background-color-only routine hover transitions unless a component explicitly owns another motion contract.
  • A viewport-wide scroll owner around a max-width readable content column.

The Series-specific relationship section is a default-expanded disclosure with a smooth, reduced-motion-aware height and opacity transition. A direct Series renders its Events on one chronological rail. An editioned Series renders Edition items containing their own phase, disposition, attendance, and counts. Edition Details uses a concurrency-safe program list rather than implying one stage or track.

When the complete media collection is empty, Thumbnail Showcase renders only the large primary placeholder. It does not draw an empty secondary-thumbnail row.

A direct Series may render one program map over its complete active Event membership. An Edition renders mutually exclusive official-location and program-Event modes, preferring mapped official locations initially. An editioned Series does not aggregate its Editions into one cross-edition map.

Map query results are complete within the declared ceiling and include honest coverage counts. The frontend adapter owns domain labels, composite Event-location identity, mode state, summaries, and canonical navigation; MapRuntime continues to own provider lifecycle, camera, clusters, controls, selection, and failure containment. See Maps for the complete spatial contract.

TanStack Query owns server state. Query keys distinguish Index pages, Series Details, Edition Details, authoring memberships, scoped Event collections, and map projections. Bounded public previews never become authoring baselines. Protected membership reads load complete paginated collections, including removable inactive targets where necessary.

Mutations invalidate or reconcile every affected direction deliberately:

  • Series scalar, link, ticket, media, direct-Event, and Edition-child changes refresh their Series projections.
  • Edition scalar, link, ticket, media, program-Event, and official-Venue changes refresh the Edition and its parent Series.
  • Event membership changes refresh Event Details references plus affected Series/Edition Details, scoped Event queries, feeds, and map collections.

Avoid broad cache clearing. Each workflow should name the projections whose truth changed.

TanStack Form is the only in-memory owner of JSON-authorable values for Add/Edit Series and Add/Edit Edition. Forms own fields, touched state, validation, dynamic row identity, dirty comparison, and accessible errors. They do not own route permissions, transport orchestration, revisions, cache invalidation, or final navigation.

Route wrappers and feature workflows own:

  • Permission-to-capability mapping.
  • Create/update mode and current public identity.
  • Expected revision progression and conflict recovery.
  • Ordered scalar, relationship, link, ticket, and media operations.
  • Partial-success state and retry from the first unfinished step.
  • Destination selection and parent-context return behavior.

Series owns direct Event membership and Edition children. Edition owns program Events and official Venues. Event forms show compact read-only Series/Edition context plus links into the owning editor; they do not become a competing membership owner.

Parent-to-child authoring navigation uses two complementary channels:

  1. A typed internal return context in the URL records the validated parent destination, relationship kind, focus target, and transition intent. No draft data is serialized into the URL.
  2. Versioned sessionStorage preserves the parent’s JSON draft across the route unmount and refresh.

Draft storage is:

  • Scoped by user, form kind, Series public ID or new, and Edition public ID or no-edition.
  • Per-tab because it uses sessionStorage.
  • Written after a 400 ms debounce.
  • Limited to schema-valid JSON and rejected when it contains File or Blob values.
  • Expired after 24 hours and removed when invalid, expired, or explicitly discarded.
  • Automatically restored only when its entity identity and known server revision match.
  • Presented for review or discard when the server revision changed or cannot be trusted.
  • Cleared for the user during logout.

The form API performs restoration; React state must not become a second complete draft owner. Dynamic links and ticket rows retain stable client identities across restore, reorder, and removal, and those form-only identities are stripped from requests and change detection.

Navigation uses real links so browser semantics remain intact. Parent-launched child forms return directly to the parent authoring context after save. Standalone saves offer an accessible choice between the canonical Details page and a relevant editing destination. The route transition uses opacity only and bypasses animation under reduced motion.

Selected browser File values remain an in-memory media draft outside TanStack Form’s JSON values. The media workflow:

  1. Saves or creates the parent once.
  2. Uploads selected files sequentially after a public identity exists.
  3. Synchronizes the complete profile/gallery collection.
  4. Retains successful uploads and the latest revision when a later step fails.
  5. Retries only unfinished uploads or the final synchronization step.

Unsaved media participates in dirty-state and navigation protection. Cross-form navigation requires an explicit save or discard decision when file state would otherwise be lost. JSON draft restoration never claims to restore browser files. An IndexedDB-backed file-draft system is not part of the current contract.

Accessibility, Responsive, And Motion Rules

Section titled “Accessibility, Responsive, And Motion Rules”
  • Page headings, forms, disclosures, relationship managers, and save-destination dialogs have visible accessible names.
  • Loading and pending states expose aria-busy; validation remains associated with its owning field.
  • Dynamic collection actions name the affected item and position.
  • Disclosure, dialog, and cross-route focus returns to a stable trigger or section target.
  • Desktop and narrow layouts preserve horizontal containment, top-aligned detail content, and viewport-wide scrolling.
  • Routine rows and cards animate background color only. Borders, shadows, and vertical position remain stable.
  • Explicit disclosure and route transitions honor reduced-motion preferences.

Use the narrowest layer that proves the change:

  • Contract tests for strict DTOs, route identity, codes, and cardinality.
  • Mocked-request and DB-backed tests for authorization, revisions, persistence, and complete relationship behavior.
  • Workflow and component tests for form ownership, draft restore, retries, cache targets, accessibility, and navigation.
  • Route integration tests for hydration, canonicalization, permissions, and page composition.
  • Deterministic browser tests for focus, history, responsive containment, theme, localization, maps, and motion.

A bounded public preview, a mocked request, and a DB-backed relationship test prove different claims; do not substitute one for another.