---
import Base from '../../layouts/Base.astro';
import CalendarEventCard from '../CalendarEventCard.astro';
import LinkedEventCard from '../LinkedEventCard.astro';
import PostCard from '../PostCard.astro';
import { useTranslations, type Lang } from '../../i18n/ui';
import { linkedEvents } from '../../data/linked-events';
import { pastMeetupPosts } from '../../data/meetups';
import { getCalendarEvents } from '../../lib/atproto/events';
import { getScope } from '../../config/scopes';
import { getPosts } from '../../lib/atproto/client';
import type { CalendarEvent } from '../../lib/atproto/events';
import type { LinkedEvent } from '../../data/linked-events';
const { lang } = Astro.props as { lang: Lang };
const t = useTranslations(lang);
// Calendar events are country-tagged (see events-account.ts): a national site shows events tagged
// with its country, the .eu aggregate shows all. Past meetups are NL photos, so they stay on .nl and
// the aggregate only. Other national sites keep the generic organizer guides regardless.
const scope = getScope(import.meta.env.PUBLIC_SITE_SCOPE);
const cc = scope.aggregate || scope.countries === 'all' ? null : scope.countries[0];
const allEvents = await getCalendarEvents();
const events = scope.aggregate ? allEvents : allEvents.filter((e) => cc != null && e.countries.includes(cc));
// Ecosystem link cards are country-tagged too: a national site shows only its own, the aggregate all.
const scopedLinkedEvents = scope.aggregate
? linkedEvents
: linkedEvents.filter((e) => cc != null && e.countries.includes(cc));
const showMeetups = scope.aggregate || cc === 'nl';
const meetups = showMeetups ? await getPosts(pastMeetupPosts) : [];
// Merge our own calendar events (full cards) with ecosystem events (stripped link cards)
// into single Upcoming / Past lists, sorted chronologically.
interface Row {
sort: number;
upcoming: boolean;
cal?: CalendarEvent;
linked?: LinkedEvent;
}
const rows: Row[] = [
...events.map((e) => ({ sort: Date.parse(e.startsAt), cal: e, upcoming: e.upcoming })),
...scopedLinkedEvents.map((e) => ({ sort: Date.parse(e.startsAt), linked: e, upcoming: e.when === 'upcoming' })),
];
const upcomingRows = rows.filter((r) => r.upcoming).sort((a, b) => a.sort - b.sort);
const pastRows = rows.filter((r) => !r.upcoming).sort((a, b) => b.sort - a.sort);
---
{t('nav.events')}
{t('events.subtitle')}
{
upcomingRows.length > 0 && (
{t('events.heading')}
{upcomingRows.map((r) =>
r.cal ? (
) : (
),
)}
)
}
{
pastRows.length > 0 && (
{t('events.past.events')}
{pastRows.map((r) =>
r.cal ? (
) : (
),
)}
)
}
{
meetups.length > 0 && (
)
}
{/* The organizer guides now live in the EU-wide handbook at docs.atproto.eu (one source for every
country), so these cards deep-link out there rather than to local /events/* pages. */}
{t('events.guides.h')}
{t('events.guides.note')}