diff --git a/src/components/EventHeroCard.astro b/src/components/EventHeroCard.astro new file mode 100644 index 0000000..f799f88 --- /dev/null +++ b/src/components/EventHeroCard.astro @@ -0,0 +1,337 @@ +--- +import Avatar from './Avatar.astro'; +import type { Event, UserPublic } from '../lib/db'; +import { eventKindLabel, redactName } from '../lib/format'; + +interface Props { + event: Event | null; + attendees: UserPublic[]; // confirmed (status='yes') + confirmedCount: number; + myRsvp: 'yes' | 'no' | 'interested' | null; +} + +const { event, attendees, confirmedCount, myRsvp } = Astro.props; + +function parseUtc(s: string): Date { + if (/T.*[Zz]$/.test(s) || /[+-]\d{2}:?\d{2}$/.test(s)) return new Date(s); + return new Date(s.replace(' ', 'T') + 'Z'); +} +function fmt(part: Intl.DateTimeFormatOptions, iso: string): string { + return new Intl.DateTimeFormat('en-GB', { ...part, timeZone: 'Europe/Copenhagen' }).format(parseUtc(iso)); +} + +const dayPadded = event ? String(parseUtc(event.starts_at).getUTCDate()).padStart(2, '0') : ''; +const weekday = event ? fmt({ weekday: 'long' }, event.starts_at).toUpperCase() : ''; +const monthShort = event ? fmt({ month: 'short' }, event.starts_at).toUpperCase() : ''; +const startTime = event ? fmt({ hour: '2-digit', minute: '2-digit', hour12: false }, event.starts_at) : ''; +const closesDay = event ? fmt({ weekday: 'long' }, event.starts_at).toUpperCase() : ''; + +const visibleAttendees = attendees.slice(0, 3); +const overflow = Math.max(0, attendees.length - visibleAttendees.length); +--- +{event ? ( +
+ +
+
+ {weekday} + {dayPadded} + {monthShort} · {startTime} +
+ +
+

Next gathering · {eventKindLabel(event.kind).toUpperCase()}

+

{event.title}

+

{event.description}

+

{event.location}

+
+ +
+ {event.duration_label && ( +

{event.duration_label.toUpperCase()}

+ )} + {visibleAttendees.length > 0 && ( +
    + {visibleAttendees.map(u => ( +
  • + {redactName(u.name)} + +
  • + ))} + {overflow > 0 && ( +
  • + +{overflow} more + +
  • + )} +
+ )} +
+
+ + +
+) : ( +
+

Nothing scheduled yet — when we have something, you'll be the first to know.

+
+)} + + diff --git a/src/pages/pulse.astro b/src/pages/pulse.astro index b151e53..8571e67 100644 --- a/src/pages/pulse.astro +++ b/src/pages/pulse.astro @@ -1,7 +1,7 @@ --- import AppLayout from '../layouts/AppLayout.astro'; import Avatar from '../components/Avatar.astro'; -import AvatarPile from '../components/AvatarPile.astro'; +import EventHeroCard from '../components/EventHeroCard.astro'; import { getUpcomingEvents, getEventBySlug, getEventAttendees, getUserRsvp, setEventRsvp, recordActivity, @@ -142,78 +142,18 @@ const members = getAllCabMembers(); )} - - {hero ? ( -
+ +
+ +
- -
-
- {weekday(hero.starts_at)} - {dayNum(hero.starts_at)} - {monthShort(hero.starts_at)} -
+ -
-

{hero.title}

-

{hero.description}

-

- {hero.location}{hero.location && ' · '}{timeStr(hero.starts_at)}{hero.duration_label ? ` · ${hero.duration_label}` : ''} -

-
-
- - - - - {comingUp.length > 0 && ( - - )} - - See all events - -
- ) : ( -
-

Nothing scheduled yet — when we have something, you'll be the first to know.

- See all events -
- )} {featured && (