Skip to main content

Developer Page Specifications

Listing Pages

Landing + 8 scoped listings. CalendarLandingPage rails + EventListingPage with filter rail.

Complete

Routes: /:lang/calendar (landing — rails-driven, not query-driven), /:lang/calendar/events (full listing, all filters), /:lang/calendar/events/countries/{countrySlug}, /:lang/calendar/events/categories/{categorySlug}, /:lang/calendar/events/audiences/{audienceSlug}, /:lang/calendar/events/stages/{stageSlug}, /:lang/calendar/this-week, /:lang/calendar/closing-soon. 8 routes total, 2 components: CalendarLandingPage (rails) + EventListingPage (filter+grid, reused via route.data.scope).

Landing page sections (/:lang/calendar)

  1. A · Hero (eyebrow + H1 + 1-line lede + 2 CTAs: "Submit an event" + "View all events")
  2. B · This-week rail (horizontal scroll, events within ±7 days of NOW)
  3. C · Closing-soon rail (deadlines within 7 days, warning-tinted deadline chips)
  4. D · By-country grid (16 flag tiles, each linking to /calendar/events/countries/{slug} with live event count)
  5. E · By-category grid (17 category tiles)
  6. F · Spotlight (at most 1 editorialPriority=spotlight event, full-width banner)
  7. G · Submit-an-event CTA block (one-line pitch → routerLink to /:lang/calendar/submit)
  8. H · Footer

Listing page sections (/:lang/calendar/events*)

  1. A · Hero (scoped title — "All events" / "Events in Egypt" / "Demo days" — + result count + active filter chips)
  2. B · Filter rail (left desktop sticky, bottom-drawer mobile): country / category / audience / stage / status / mode (physical/online/hybrid)
  3. C · Grid (3-col desktop, 2-col tablet, 1-col mobile)
  4. D · Counter at bottom ("Showing X of Y events")
  5. E · No pagination — infinite scroll, 24 cards/batch

Event card fields (canonical <app-event-card>)

date chip
NEVER-collapse element. Dominant in card hierarchy. Format: D-{N} for upcoming, "LIVE NOW" for status=live, "+{N}d" for completed, formatted full date for ≥30 days out.
flag + country chip
Source: Event.CountryCode + Country.NameLang. Display: flag emoji + abbreviated country name when card narrow.
category icon + label
Source: Event.Category. Lookup icon from CATEGORY_ICONS (e.g. demo-day → presentation icon, hackathon → terminal icon).
status badge
Computed from times. Tints: upcoming=neutral / open=primary / closing-soon=warning / live=accent pulse / completed=muted / postponed=amber / cancelled=destructive.
title + organizer
Source: EventLang.Title + Event.OrganizerName. Title H3, organizer t-meta below.
mode chip
Source: Event.Mode (physical | online | hybrid). Small chip in card foot.
CTAs
Primary: routerLink to /:lang/calendar/events/{slug}. Secondary (when registrationUrl OR applyUrl): outbound to that URL with target=_blank.