import moment from 'moment' import { fetchUpcomingOccurrences } from '@/fetch/eventOccurrences' import { fetchGroup, fetchAllGroups } from '@/fetch/group' import { fetchParish, fetchAllParishes } from '@/fetch/parish' import { transformOccurrences } from '@/utils/dto/events' import { PageHeader } from '@/compositions/PageHeader/PageHeader' import { Section } from '@/components/Section/Section' import { Container } from '@/components/Container/Container' import { EventRow } from '@/components/EventRow/EventRow' import { NextPrevButtons } from '@/components/NextPrevButtons/NextPrevButtons' import { EventFilterBar } from '@/compositions/EventFilterBar/EventFilterBar' import { AdminMenu } from '@/components/AdminMenu/AdminMenu' import Error from '@/components/Error/Error' import { isAuthenticated } from '@/utils/auth' import { Title } from '@/components/Title/Title' import { HR } from '@/components/HorizontalRule/HorizontalRule' import { P } from '@/components/Text/Paragraph' const DATE_FMT = 'YYYY-MM-DD' const PAGE_SIZE = 10 type Query = { group?: string parish?: string from?: string to?: string page?: string } const parseDate = (value: string | undefined): Date | undefined => { if (!value) return undefined const m = moment(value, DATE_FMT, true) return m.isValid() ? m.toDate() : undefined } const buildHref = (q: Query, page: number): string => { const params = new URLSearchParams() if (q.group) params.set('group', q.group) if (q.parish) params.set('parish', q.parish) if (q.from) params.set('from', q.from) if (q.to) params.set('to', q.to) if (page > 1) params.set('page', String(page)) const qs = params.toString() return qs ? `/veranstaltungen?${qs}` : '/veranstaltungen' } export default async function EventsOverviewPage({ searchParams, }: { searchParams: Promise }) { const authenticated = await isAuthenticated() const query = await searchParams const fromDate = parseDate(query.from) ?? moment().startOf('day').toDate() const toDate = parseDate(query.to) const parsedPage = parseInt(query.page ?? '1', 10) const page = Number.isFinite(parsedPage) && parsedPage > 0 ? parsedPage : 1 const [allGroups, allParishes, groupDoc, parishDoc] = await Promise.all([ fetchAllGroups(), fetchAllParishes(), query.group ? fetchGroup(query.group) : Promise.resolve(null), query.parish ? fetchParish(query.parish) : Promise.resolve(null), ]) const paginated = await fetchUpcomingOccurrences({ limit: PAGE_SIZE, page, fromDate, toDate, groupId: groupDoc?.id, parishId: parishDoc?.id, }) if (!paginated) { return } const events = transformOccurrences(paginated.docs) const initial = { group: groupDoc?.slug ?? undefined, parish: parishDoc?.slug ?? undefined, from: query.from && parseDate(query.from) ? query.from : undefined, to: query.to && parseDate(query.to) ? query.to : undefined, } return ( <>
<P width={"3/4"}> Entdecken Sie unsere kommenden Veranstaltungen und seien Sie dabei! Hier finden Sie alle Termine, Informationen und Highlights auf einen Blick. </P> <EventFilterBar groups={allGroups.docs.map((g) => ({ slug: g.slug, name: g.name }))} parishes={allParishes.docs.map((p) => ({ slug: p.slug, name: p.name }))} initial={initial} /> </Container> <HR /> </Section> <Section padding={'small'} paddingBottom={'large'}> <Container> {events.map((e) => ( <EventRow key={e.id} date={e.date} end={e.end} title={e.title} href={e.href} location={e.location} cancelled={e.cancelled} /> ))} {events.length === 0 && <p>Keine Veranstaltungen gefunden</p>} </Container> </Section> <AdminMenu collection={'event'} isAuthenticated={authenticated} /> {(paginated.hasPrevPage || paginated.hasNextPage) && ( <Section padding={'small'}> <NextPrevButtons prev={ paginated.hasPrevPage && paginated.prevPage ? { href: buildHref(query, paginated.prevPage), text: 'Vorige Seite' } : undefined } next={ paginated.hasNextPage && paginated.nextPage ? { href: buildHref(query, paginated.nextPage), text: 'Nächste Seite' } : undefined } /> </Section> )} </> ) }