230 lines
6.7 KiB
TypeScript
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}
|
|
/>
|
|
</>
|
|
)
|
|
}
|