Event Presentation
Wavemap’s implemented public Event collection surfaces share schedule and status meaning without forcing every context into one visual component. Use this page when changing the Events Index, Event typeahead, Artist event previews, compact schedule formatting, status tags, canonical Event navigation, or canonical Event-media projections.
This guidance covers the product-quality Events Index and the implemented Artist Details entry point. Event Details is still a collaborator-led implementation surface. Its expanded schedule, relationship, metadata, and responsive composition should not be inferred from the compact collection patterns described here.
Semantic Boundary
Section titled “Semantic Boundary”Event summaries carry server-owned native schedule and state data. Frontend presentation preserves these distinctions:
- Organizer-authored local dates, local times, and reference time zone remain the primary compact calendar context.
- Date-only boundaries never pass through viewer-zone instant conversion or acquire a fake midnight.
- An omitted end remains unknown; collection UI does not manufacture a duration.
- Administrative state and derived temporal phase remain separate signals. The normal
scheduledstate can stay quiet, while cancellation does not replaceupcoming,current,historical, orindeterminatephase meaning. - Physical and digital attendance are contexts of one Event. A hybrid Event is not rendered as duplicate results.
buildEventSchedulePresentationParts(...) owns locale-aware schedule parts, and
buildCompactEventScheduleLabel(...) composes the organizer-calendar label used by the Index, Event typeahead, and
Artist preview table. computeEventTemporalPhaseTagStyles(...) maps native temporal phases onto the established Event
tag presentation. Page and domain wrappers continue to own translated labels and decide where those prepared values
appear.
Composition By Context
Section titled “Composition By Context”The Artists Index is the page-shell and browsing-state analogue for the Events Index, not the Event-card design target. Keep these Event presentations distinct:
| Context | Presentation Contract |
|---|---|
| Index gallery | Reusable horizontal EventCard with media beside name, attendance, compact schedule, and state. |
| Index table | EventTable with responsive columns and row navigation over the same summary DTO. |
| Index feed | Page-local, poster-forward EventFeedCard with a title/state footer and separate schedule line. |
| Artist Details preview | Dense RecentEventsTable constrained to a small organizer-calendar-ordered relationship summary. |
| Event typeahead | Compact page/domain result row for direct selection or viewing all matching Index results. |
Do not introduce a universal Event preview component across these contexts. Share semantic adapters and leaf presentation only where ownership, density, actions, and input data genuinely match. The Index page owns API hooks, URL state, saved views, translation, DTO-to-presentation adaptation, canonical navigation, and the animated view handoff. Cards and tables receive prepared display values and public-identity actions.
Browsing And Navigation
Section titled “Browsing And Navigation”Table and gallery use the offset-paginated Events query. The feed uses its dedicated opaque cursor contract so an incrementally loaded stream has stable continuation semantics. Filters, sorts, search, and selected view remain URL-owned page state; cursor continuation remains transient query-cache state.
Every Event action resolves to the localized canonical slug~publicId detail path. The immutable public ID is
authoritative and the slug is readable but replaceable. Artist Details provides two deliberate entry points:
- Selecting a preview row navigates directly to that Event’s canonical route.
- View All Events carries
artistPublicIdinto the Events Index. The relationship scope survives table, gallery, feed, reload, and URL serialization, but does not enter a general saved view.
The browser journey protects this handoff across all three Index views and then verifies canonical Event navigation. Future Venue, Event Series, dashboard, search, calendar, structured-data, and notification entry points should be added only when their owning surfaces have a stable public-navigation contract.
Result-View Handoff
Section titled “Result-View Handoff”Changing between table, gallery, and feed acknowledges the requested view immediately and uses the established short fade state machine. Only the outgoing result subtree remains mounted and inert during exit; only the latest requested view mounts afterward. The handoff reuses offset or cursor query caches instead of treating a presentation change as a new pagination architecture.
Keep the following proof boundaries separate:
- Page integration tests own URL parsing, hydration, live-region copy, result counts, and view state.
- Component tests own card, table, feed, formatter, status, and accessibility contracts.
- Focused browser tests own real navigation, responsive controls, focus recovery, eager view acknowledgement, and canonical-route behavior.
Event Media Boundary
Section titled “Event Media Boundary”Event collection surfaces consume backend-derived canonical Poster data. The compatibility convenience
profileImageURL is computed from ready profile-purpose event_media; it is not a writable scalar Event field. Ordered
media DTOs preserve full and thumbnail sources, blur preview, intrinsic dimensions, alt text, purpose, lifecycle status,
and purpose-local order without exposing provider locators.
One Event-owned presentation adapter applies density without flattening the compositions:
- Gallery cards, table rows, typeahead results, and Artist Details previews prefer the thumbnail and fall back to the full source.
- The poster-forward feed uses the full source where its responsive composition warrants that cost.
- Authored alt text is preserved; the Event name is the meaningful fallback when the composition requires an accessible image name.
- Missing or failed media continues through each surface’s established placeholder and error state.
- Blur previews and trustworthy dimensions are carried through rather than recomputed in the browser.
Event media mutations invalidate Event details, feed, offset Index queries, Event typeahead, and Artist-scoped Event queries deliberately. Canonical navigation can refresh server-rendered metadata, but one page cache must not become global truth or invalidate unrelated Artist details.
Historical external image URLs remain renderable through backend-owned legacy URL resolution and existing Next image patterns. New canonical uploads use the configured backend/CloudFront delivery path; frontend hostname exceptions are not a substitute for storage and delivery ownership.
Event Details Boundary
Section titled “Event Details Boundary”Event Details may reuse compact schedule parts, native status semantics, public identity, and the stable ordered, render-ready media DTO. It must still prove its own expanded organizer/viewer schedule explanation, attendance hierarchy, relationship density, metadata, accessibility, and responsive layout. Re-inventory shared contracts only after that live page exists; do not generalize from collection surfaces into the collaborator’s learning sandbox.
Event Relationship Read Boundaries
Section titled “Event Relationship Read Boundaries”Event Details currently returns an unpaginated artists collection of EventArtistReferenceDTO values. The Artist query’s inner LIMIT 1 chooses a profile image per Artist; it does not truncate the lineup. The 200-ID relationship mutation limit bounds one write request, not the read collection. A complete public collection can supply the first 30 tags, a remaining count of length - 30 above that threshold, and every Artist in the full-lineup modal without a second list request or stored count. Preserve response order and key entries by immutable public ID, including equal names or slugs.
Both public Event Details and the combined structured-data Event payload include only active Artists. The backend applies that eligibility rule; the reference needs no lifecycle discriminator or browser filter. The protected GET /api/v1/events/:eventID/artists returns EventArtistsMembershipResponseDTO: Event public ID, revision and the complete ordered items collection, including inactive linked Artists. It requires manage-event-artist-relationships and sends Cache-Control: private, no-store. That editor collection stays separate from the public Event cache and must never supply the public lineup.
eventSeriesContext.directEventSeries and editionPrograms are complete public membership collections. The latter keeps each Edition paired with its own Series. Active lifecycle and structure checks suppress traversal through inactive parents or Editions; cancellation alone does not suppress an active Edition. Render every supplied membership as a separate Part of row, including multiple Editions under one Series. The Artist threshold does not apply, and no preview total or overflow destination is needed.
Build Artist destinations with buildArtistDetailsRoute, direct and parent Series destinations with buildEventSeriesDetailsRoute, and Edition destinations with buildEventSeriesEditionDetailsRoute({ eventSeries, edition }). Use the supplied current slugs and public IDs; keep the Series and Edition links independent, and let the page’s established navigation owner apply the locale. Do not deduplicate memberships by display name, flatten Editions into direct memberships, or infer missing hierarchy. These read and helper checks do not establish the learner page’s modal, focus, localization or responsive rendering.
Structured-Data Server Consumer Contract
Section titled “Structured-Data Server Consumer Contract”The public GET /api/v1/events/:eventID/structured-data route returns EventStructuredDataResponseDTO: the current public Event plus its backend-owned projection in one API success envelope. It reuses the active Event read once, excludes persistence identity, and sends Cache-Control: no-store. Invalid IDs or query inputs return 400, missing/inactive/hard-deleted Events return the existing keyed 404, and read/projection failures return an error envelope. Query input is empty and strict; callers cannot submit schedules, relationships or canonical hosts.
The projection preserves authored date-only, timed and supported mixed boundaries, omits unknown ends, and retains attendance/cancellation meaning. Place entries expose public identity/name without invented address data. A single direct Series membership can supply the existing singular superEvent; multiple direct memberships omit it rather than choosing a parent. Edition programs remain available in Event data but have no inferred JSON-LD hierarchy. Extending those semantics requires a separate decision.
Transport Event and Series @id/url values are canonical local path references without locale or origin. Under the Event route directory, metadata.ts owns buildEventMetadataCanonicalURL and buildEventPageMetadata; structuredData.ts binds the same selected locale and trusted NEXT_PUBLIC_BASE_URL to those identities without re-projecting schedule or relationship meaning. The API response must pass through this binding before embedding. The JSON-LD Event URL and metadata canonical URL therefore use the same owner and exclude tracking/search parameters.
The module-level getCachedEventStructuredData in serverLoaders.ts follows the Series React-cache pattern. Metadata and page composition import that same loader and pass the resolved public ID. The combined result supplies metadata, JSON-LD and { event: result.event } for the existing Event query hydration key. Do not separately request scalar Event details on the server or keep a process-global cache. React shares success and rejection only within one server request; a later request reads again.
EventStructuredDataScript emits a native application/ld+json script, escaping every < after JSON serialization so text cannot close the HTML script element. It preserves the original JSON values, including markup-like authored text; it does not sanitize or rewrite Event descriptions. This follows Next.js JSON-LD guidance. The API/client, canonical binder and script contract have focused proof, including real React Server Component request caching, HTML-parser round trips, and PostgreSQL active/deleted reads.
Final Event-page integration remains learner work: resolve/validate public identity, share the loader between generateMetadata and rendering, redirect stale/legacy routes before emitting a script, hydrate the Event query from the combined read, and render the resolved document once. Map 404 to the existing notFound behavior and let other delivery/validation failures reach the page error boundary; emit no fabricated or stale fallback JSON-LD. The support tests do not claim that this route wiring, metadata copy, or visible page composition is complete.
What Makes This Page Stale
Section titled “What Makes This Page Stale”Review this page when the Event summary DTO, compact schedule adapter, administrative or temporal-state vocabulary, Index view/pagination ownership, Artist relationship scope, canonical route shape, or Event media read boundary changes. Review it again when Event Details is implemented and the full public page family can supply second-context evidence for expanded presentation.
Related Pages
Section titled “Related Pages”- Event Scheduling Architecture for authored and server-owned schedule semantics.
- Query Controls And Browsing State for URL state, saved views, search, and collection-query ownership.
- Public Entity Identifiers for canonical public routes.
- Components for reusable-component and page/domain ownership.
- State for URL, query-cache, transition, and workflow state boundaries.
- Admin Event Scheduling for editor-facing schedule vocabulary.