church-website/src/pageComponents/Event/Event.tsx
2026-06-05 13:43:17 +02:00

230 lines
6.7 KiB
TypeScript

import styles from "./styles.module.scss"
import { ContactPerson, Document, Event, Location } from '@/payload-types'
import { Section } from '@/components/Section/Section'
import { Title } from '@/components/Title/Title'
import { Container } from '@/components/Container/Container'
import { Col } from '@/components/Flex/Col'
import { Pill } from '@/components/Pill/Pill'
import { useDate } from '@/hooks/useCompactDate'
import { readableDateTime } from '@/utils/readableDate'
import { TextDiv } from '@/components/Text/TextDiv'
import { Button } from '@/components/Button/Button'
import Image, { StaticImageData } from 'next/image'
import { locationString } from '@/utils/dto/location'
import { ContactPerson2 } from '@/components/ContactPerson2/ContactPerson2'
import { getPhoto } from '@/utils/dto/gallery'
import { AdminMenu } from '@/components/AdminMenu/AdminMenu'
import { EventRow } from '@/components/EventRow/EventRow'
import { Row } from '@/components/Flex/Row'
import classNames from 'classnames'
type UpcomingOccurrence = {
id: string
date: string
end?: string
title: string
href: string
location: string
cancelled: boolean
}
type EventProps = {
id: string,
title: string,
date: string,
endDateTime?: string,
createdAt: string,
cancelled: boolean,
recurrenceType?: Event['recurrenceType'],
recurrenceDescription?: string,
location: string | Location,
description: string,
shortDescription: string,
contact?: string | ContactPerson,
group?: string,
flyer?: Document,
photo?: StaticImageData,
rsvpLink?: string,
isAuthenticated: boolean,
upcomingOccurrences?: UpcomingOccurrence[],
}
export function EventPage(
{
id,
title,
date,
endDateTime,
createdAt,
cancelled,
recurrenceType,
recurrenceDescription,
location,
description,
shortDescription,
contact,
flyer,
group,
photo,
rsvpLink,
isAuthenticated,
upcomingOccurrences,
}: EventProps
) {
const published = useDate(createdAt)
const readableDate = readableDateTime(date, endDateTime)
const where = locationString(location);
const contactPersonPhoto = typeof contact === "object" ? getPhoto("thumbnail", contact.photo) : undefined;
const isRecurring = recurrenceType && recurrenceType !== 'none'
const hasOccurrences = upcomingOccurrences && upcomingOccurrences.length > 0;
const dateOrRecurrence = recurrenceDescription ?? readableDate
return (
<>
<Section paddingBottom={"small"} backgroundColor={"off-white"}>
<Container>
<Title
title={title}
size={"xl"}
color={"contrast"}
cancelled={cancelled}
/>
</Container>
<div className={styles.header}>
<div className={styles.headerText}>
<p>
{shortDescription}
</p>
<p className={styles.published}>
Publiziert am {published}
</p>
<div className={styles.pills}>
{ isRecurring &&
<Pill>Regelmäßig</Pill>
}
{ cancelled &&
<Pill schema={"contrast"}>Abgesagt</Pill>
}
</div>
</div>
<div>
{ photo &&
<Image
src={photo}
className={styles.photo}
alt={"Veranstaltungsbild"}
unoptimized={true}
/>
}
</div>
</div>
</Section>
<Section padding={"medium"}>
<Container>
<Title
size={"md"}
title={title}
subtitle={`${dateOrRecurrence} - ${typeof location === "object" ? location.name : 'd'}`}
fontStyle={"sans-serif"}
align={"center"}
/>
<Section padding={"medium"}>
<Row>
<Col>
<Title
size={"md"}
title={"Einladung"}
fontStyle={"sans-serif"}
align={"center"}
/>
<div className={classNames({
[styles.description]: true,
[styles.padding]: !hasOccurrences
})}>
<TextDiv text={description} />
<br/>
<Title title={"Location"} size={"sm"} align={"center"} fontStyle={"sans-serif"}/>
<TextDiv text={where} />
{ typeof contact !== "undefined" &&
<>
<br/>
<Title title={"Ansprechperson"} size={"sm"} align={"center"} fontStyle={"sans-serif"}/>
<ContactPerson2
contact={contact}
photo={contactPersonPhoto}/>
</>
}
</div>
{ (typeof flyer === "object" || group || rsvpLink) &&
<Section padding={"small"}>
<div className={styles.buttons}>
{ rsvpLink &&
<Button size={"md"} href={rsvpLink} target={"_blank"} schema={"contrast"}>
Anmelden
</Button>
}
{ typeof flyer === "object" && flyer.url &&
<Button size={"md"} href={flyer.url}>Flyer herunterladen</Button>
}
{ group &&
<Button
size={"md"}
schema={"shade"}
href={`/gruppe/${group}`}
>Erfahre mehr zur Gruppe</Button>
}
</div>
</Section>
}
</Col>
{ upcomingOccurrences && upcomingOccurrences.length > 0 &&
<Col>
<Title
title={"Nächste Termine"}
size={"md"}
color={"contrast"}
/>
{ upcomingOccurrences.map(o =>
<EventRow
key={o.id}
date={o.date}
end={o.end}
title={o.title}
href={o.href}
location={o.location}
cancelled={o.cancelled}
color={"contrast"}
/>
)}
</Col>
}
</Row>
</Section>
</Container>
</Section>
<AdminMenu
collection={"event"}
id={id}
isAuthenticated={isAuthenticated}
/>
</>
)
}