fix: storybook
This commit is contained in:
parent
dba13d1d31
commit
3fab363e1f
23 changed files with 663 additions and 626 deletions
|
|
@ -19,6 +19,9 @@ const preview: Preview = {
|
|||
},
|
||||
],
|
||||
parameters: {
|
||||
nextjs: {
|
||||
appDirectory: true,
|
||||
},
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ import { withPayload } from '@payloadcms/next/withPayload'
|
|||
const nextConfig = {
|
||||
// Your Next.js config here
|
||||
output: 'standalone',
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,40 +1,7 @@
|
|||
import { fetchEvents } from '@/fetch/events'
|
||||
import { fetchWorship } from '@/fetch/worship'
|
||||
import { fetchBlogPosts } from '@/fetch/blog'
|
||||
import { fetchHighlights } from '@/fetch/highlights'
|
||||
import { Home } from '@/pageComponents/Home/Home'
|
||||
import moment from 'moment'
|
||||
import { fetchLastAnnouncement, fetchLastAnnouncements } from '@/fetch/announcement'
|
||||
import { perParish } from '@/utils/dto/perParish'
|
||||
import { fetchLastCalendars } from '@/fetch/calendar'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
export default async function HomePage() {
|
||||
|
||||
const fromDate = moment().isoWeekday(1).hours(0).minutes(0);
|
||||
const tillDate = moment().isoWeekday(7).hours(23).minutes(59);
|
||||
const events = await fetchEvents()
|
||||
const worship = await fetchWorship({
|
||||
fromDate: fromDate.toDate(),
|
||||
tillDate: tillDate.toDate(),
|
||||
});
|
||||
const blog = await fetchBlogPosts(true)
|
||||
const highlights = await fetchHighlights()
|
||||
const announcements = await fetchLastAnnouncements();
|
||||
const announcementsLinks = announcements ? perParish(announcements) : [];
|
||||
const calendars = await fetchLastCalendars();
|
||||
const calendarsLinks = calendars ? perParish(calendars) : [];
|
||||
|
||||
|
||||
return (
|
||||
<Home
|
||||
events={events?.docs || []}
|
||||
worship={worship?.docs || []}
|
||||
blog={blog?.docs || []}
|
||||
highlights={highlights?.docs || []}
|
||||
announcements={announcementsLinks}
|
||||
calendars={calendarsLinks}
|
||||
/>
|
||||
)
|
||||
return <Home />
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ const makeAdText = (text: string): SerializedEditorState =>
|
|||
},
|
||||
],
|
||||
},
|
||||
}) as SerializedEditorState
|
||||
}) as unknown as SerializedEditorState
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ const makeAdText = (text: string): SerializedEditorState =>
|
|||
},
|
||||
],
|
||||
},
|
||||
}) as SerializedEditorState
|
||||
}) as unknown as SerializedEditorState
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const sampleState: SerializedEditorState = {
|
|||
},
|
||||
],
|
||||
},
|
||||
} as SerializedEditorState
|
||||
} as unknown as SerializedEditorState
|
||||
|
||||
export const ThreeFourth: Story = {
|
||||
args: {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
import { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { ContactForm } from './ContactForm'
|
||||
import { ContactFormView, ContactFormState } from './ContactFormView'
|
||||
|
||||
const meta: Meta<typeof ContactForm> = {
|
||||
component: ContactForm,
|
||||
const noopAction = async (): Promise<ContactFormState> => ({
|
||||
message: 'Storybook: form submission is a no-op.',
|
||||
})
|
||||
|
||||
const meta: Meta<typeof ContactFormView> = {
|
||||
component: ContactFormView,
|
||||
args: {
|
||||
action: noopAction,
|
||||
},
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof ContactForm>;
|
||||
type Story = StoryObj<typeof ContactFormView>
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
schema: 'base',
|
||||
toEmail: 'test@test.com'
|
||||
},
|
||||
}
|
||||
|
||||
export const Schema: Story = {
|
||||
args: {
|
||||
schema: 'contrast',
|
||||
toEmail: 'test@test.com'
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +1,14 @@
|
|||
'use client'
|
||||
|
||||
import { Input } from '@/components/Input/Input'
|
||||
import { Button } from '@/components/Button/Button'
|
||||
import styles from "./styles.module.scss"
|
||||
import classNames from 'classnames'
|
||||
import { send } from '@/utils/actions'
|
||||
import { useActionState } from 'react'
|
||||
import { ContactFormView } from './ContactFormView'
|
||||
|
||||
type ContactFormProps = {
|
||||
schema?: "base" | "contrast",
|
||||
schema?: 'base' | 'contrast'
|
||||
toEmail: string
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
message: '',
|
||||
export const ContactForm = ({ schema, toEmail }: ContactFormProps) => {
|
||||
const sendWithEmail = send.bind(null, toEmail)
|
||||
return <ContactFormView schema={schema} action={sendWithEmail} />
|
||||
}
|
||||
|
||||
export const ContactForm = ({schema, toEmail}: ContactFormProps) => {
|
||||
|
||||
const sendWithEmail = send.bind(null, toEmail);
|
||||
const [state, formAction, pending] = useActionState(sendWithEmail, initialState)
|
||||
|
||||
return (
|
||||
<form action={formAction}>
|
||||
<div className={classNames(styles.row, styles.firsRow)}>
|
||||
<Input name={"name"} type={"text"} placeholder={"Name"} />
|
||||
<Input name={"email"} type={"email"} placeholder={"E-Mail Adresse"} />
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<Input name={"subject"} type={"text"} placeholder={"Thema"} />
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<Input name={"message"} type={"textarea"} placeholder={"Ihre Nachricht"} />
|
||||
</div>
|
||||
<p>
|
||||
{state.message}
|
||||
</p>
|
||||
<div className={styles.row}>
|
||||
<Button size={"lg"} type={"submit"} schema={schema} disabled={pending}>Abschicken</Button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
51
src/compositions/ContactForm/ContactFormView.tsx
Normal file
51
src/compositions/ContactForm/ContactFormView.tsx
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
'use client'
|
||||
|
||||
import { Input } from '@/components/Input/Input'
|
||||
import { Button } from '@/components/Button/Button'
|
||||
import styles from './styles.module.scss'
|
||||
import classNames from 'classnames'
|
||||
import { useActionState } from 'react'
|
||||
|
||||
export type ContactFormState = {
|
||||
message: string
|
||||
errors?: Record<string, string[] | undefined>
|
||||
}
|
||||
|
||||
export type ContactFormAction = (
|
||||
prevState: ContactFormState,
|
||||
formData: FormData,
|
||||
) => Promise<ContactFormState> | ContactFormState
|
||||
|
||||
type ContactFormViewProps = {
|
||||
schema?: 'base' | 'contrast'
|
||||
action: ContactFormAction
|
||||
}
|
||||
|
||||
const initialState: ContactFormState = {
|
||||
message: '',
|
||||
}
|
||||
|
||||
export const ContactFormView = ({ schema, action }: ContactFormViewProps) => {
|
||||
const [state, formAction, pending] = useActionState(action, initialState)
|
||||
|
||||
return (
|
||||
<form action={formAction}>
|
||||
<div className={classNames(styles.row, styles.firsRow)}>
|
||||
<Input name={'name'} type={'text'} placeholder={'Name'} />
|
||||
<Input name={'email'} type={'email'} placeholder={'E-Mail Adresse'} />
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<Input name={'subject'} type={'text'} placeholder={'Thema'} />
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<Input name={'message'} type={'textarea'} placeholder={'Ihre Nachricht'} />
|
||||
</div>
|
||||
<p>{state.message}</p>
|
||||
<div className={styles.row}>
|
||||
<Button size={'lg'} type={'submit'} schema={schema} disabled={pending}>
|
||||
Abschicken
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,17 +1,23 @@
|
|||
import { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { ContactSection } from './ContactSection'
|
||||
import { ContactSectionView } from './ContactSectionView'
|
||||
import { ContactFormView, ContactFormState } from '@/compositions/ContactForm/ContactFormView'
|
||||
|
||||
const meta: Meta<typeof ContactSection> = {
|
||||
component: ContactSection,
|
||||
const noopAction = async (): Promise<ContactFormState> => ({
|
||||
message: 'Storybook: form submission is a no-op.',
|
||||
})
|
||||
|
||||
const meta: Meta<typeof ContactSectionView> = {
|
||||
component: ContactSectionView,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof ContactSection>;
|
||||
type Story = StoryObj<typeof ContactSectionView>
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: "Kontakt",
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel dolor semper, consectetur augue quis, elementum tellus. Nulla ut porta lorem. Nulla posuere quam nisi, ut porttitor diam dignissim eget. Morbi imperdiet et lectus quis dapibus. Cras sollicitudin est augue, vel rhoncus massa elementum vitae. Donec sagittis pulvinar nibh ultrices tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus.',
|
||||
toEmail: 'kontak@test.com'
|
||||
title: 'Kontakt',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel dolor semper, consectetur augue quis, elementum tellus. Nulla ut porta lorem. Nulla posuere quam nisi, ut porttitor diam dignissim eget. Morbi imperdiet et lectus quis dapibus. Cras sollicitudin est augue, vel rhoncus massa elementum vitae. Donec sagittis pulvinar nibh ultrices tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus.',
|
||||
form: <ContactFormView action={noopAction} />,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,28 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { ContactForm } from '@/compositions/ContactForm/ContactForm'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { TextDiv } from '@/components/Text/TextDiv'
|
||||
import { ContactSectionView } from './ContactSectionView'
|
||||
|
||||
type ContactSectionProps = {
|
||||
title: string,
|
||||
description: string,
|
||||
title: string
|
||||
description: string
|
||||
backgroundColor?: 'off-white'
|
||||
schema?: 'base' | 'contrast'
|
||||
toEmail: string
|
||||
}
|
||||
|
||||
|
||||
export const ContactSection = ({title, description, schema, backgroundColor, toEmail}: ContactSectionProps) => {
|
||||
export const ContactSection = ({
|
||||
title,
|
||||
description,
|
||||
schema,
|
||||
backgroundColor,
|
||||
toEmail,
|
||||
}: ContactSectionProps) => {
|
||||
return (
|
||||
<Section backgroundColor={backgroundColor}>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<Title title={title} size={"md"} color={schema}/>
|
||||
<TextDiv text={description} />
|
||||
</Col>
|
||||
<Col>
|
||||
<ContactForm schema={schema} toEmail={toEmail}/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
<ContactSectionView
|
||||
title={title}
|
||||
description={description}
|
||||
schema={schema}
|
||||
backgroundColor={backgroundColor}
|
||||
form={<ContactForm schema={schema} toEmail={toEmail} />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
37
src/compositions/ContactSection/ContactSectionView.tsx
Normal file
37
src/compositions/ContactSection/ContactSectionView.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { TextDiv } from '@/components/Text/TextDiv'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
type ContactSectionViewProps = {
|
||||
title: string
|
||||
description: string
|
||||
backgroundColor?: 'off-white'
|
||||
schema?: 'base' | 'contrast'
|
||||
form: ReactNode
|
||||
}
|
||||
|
||||
export const ContactSectionView = ({
|
||||
title,
|
||||
description,
|
||||
schema,
|
||||
backgroundColor,
|
||||
form,
|
||||
}: ContactSectionViewProps) => {
|
||||
return (
|
||||
<Section backgroundColor={backgroundColor}>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<Title title={title} size={'md'} color={schema} />
|
||||
<TextDiv text={description} />
|
||||
</Col>
|
||||
<Col>{form}</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,13 +1,45 @@
|
|||
import { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { Footer } from './Footer'
|
||||
import type { Footer } from '@/payload-types'
|
||||
import { FooterView } from './FooterView'
|
||||
|
||||
const meta: Meta<typeof Footer> = {
|
||||
component: Footer,
|
||||
const mockFooter: Footer = {
|
||||
id: 'mock-footer',
|
||||
groups: [
|
||||
{
|
||||
title: 'Pfarrei',
|
||||
links: [
|
||||
{ label: 'Über uns', href: '/ueber-uns' },
|
||||
{ label: 'Kontakt', href: '/kontakt' },
|
||||
{ label: 'Gemeinden', href: '/gemeinden' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Service',
|
||||
links: [
|
||||
{ label: 'Gottesdienste', href: '/gottesdienst' },
|
||||
{ label: 'Veranstaltungen', href: '/veranstaltungen' },
|
||||
{ label: 'Blog', href: '/blog' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof Footer>;
|
||||
const mockPrayers = [
|
||||
'Herr, gib mir heute die Gelassenheit, Dinge hinzunehmen, die ich nicht ändern kann.',
|
||||
'Vater unser im Himmel, geheiligt werde dein Name.',
|
||||
'Gegrüßet seist du, Maria, voll der Gnade.',
|
||||
]
|
||||
|
||||
const meta: Meta<typeof FooterView> = {
|
||||
component: FooterView,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof FooterView>
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
}
|
||||
args: {
|
||||
prayers: mockPrayers,
|
||||
footer: mockFooter,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Logo } from '@/components/Logo/Logo'
|
||||
import styles from './styles.module.scss'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { RandomPrayer } from '@/components/RandomPrayer/RandomPrayer'
|
||||
import Link from 'next/link'
|
||||
import { fetchPrayers } from '@/fetch/prayers'
|
||||
import { fetchFooter } from '@/fetch/footer'
|
||||
import { FooterView } from './FooterView'
|
||||
|
||||
export const Footer = async () => {
|
||||
const [prayers, footer] = await Promise.all([
|
||||
|
|
@ -15,48 +8,5 @@ export const Footer = async () => {
|
|||
fetchFooter(),
|
||||
])
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Section backgroundColor="soft">
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<br />
|
||||
<Logo
|
||||
color={'#ffffff'}
|
||||
textColor={'var(--base-color)'}
|
||||
withText={true}
|
||||
height={100}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<Row gap={25}>
|
||||
{footer.groups?.map((group, i) => (
|
||||
<Col key={i}>
|
||||
<p>
|
||||
<strong>{group.title}</strong>
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
{group.links?.map((link, j) => (
|
||||
<li key={j}>
|
||||
<Link href={link.href}>{link.label}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Col>
|
||||
))}
|
||||
<Col>
|
||||
<p>
|
||||
<strong>Stoßgebet</strong>
|
||||
</p>
|
||||
<RandomPrayer prayers={prayers} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
return <FooterView prayers={prayers} footer={footer} />
|
||||
}
|
||||
|
|
|
|||
61
src/compositions/Footer/FooterView.tsx
Normal file
61
src/compositions/Footer/FooterView.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Logo } from '@/components/Logo/Logo'
|
||||
import styles from './styles.module.scss'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { RandomPrayer } from '@/components/RandomPrayer/RandomPrayer'
|
||||
import Link from 'next/link'
|
||||
import type { Footer } from '@/payload-types'
|
||||
|
||||
type FooterViewProps = {
|
||||
prayers: string[]
|
||||
footer: Footer
|
||||
}
|
||||
|
||||
export const FooterView = ({ prayers, footer }: FooterViewProps) => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Section backgroundColor="soft">
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<br />
|
||||
<Logo
|
||||
color={'#ffffff'}
|
||||
textColor={'var(--base-color)'}
|
||||
withText={true}
|
||||
height={100}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<Row gap={25}>
|
||||
{footer.groups?.map((group, i) => (
|
||||
<Col key={i}>
|
||||
<p>
|
||||
<strong>{group.title}</strong>
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
{group.links?.map((link, j) => (
|
||||
<li key={j}>
|
||||
<Link href={link.href}>{link.label}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Col>
|
||||
))}
|
||||
<Col>
|
||||
<p>
|
||||
<strong>Stoßgebet</strong>
|
||||
</p>
|
||||
<RandomPrayer prayers={prayers} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,87 +1,45 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { NewsletterItem } from '@/compositions/PublicationAndNewsletter/NewsletterItem'
|
||||
import styles from "./styles.module.scss"
|
||||
import Image from 'next/image'
|
||||
import envelope from "./envelope.svg"
|
||||
import Sandbox from '@nyariv/sandboxjs'
|
||||
import { fetchLastMagazine } from '@/fetch/magazine'
|
||||
|
||||
type NewsletterData = {
|
||||
guid: string,
|
||||
title: string,
|
||||
link: string,
|
||||
pubDate: string,
|
||||
}
|
||||
import {
|
||||
PublicationAndNewsletterView,
|
||||
NewsletterArchiveItem,
|
||||
} from './PublicationAndNewsletterView'
|
||||
|
||||
export const PublicationAndNewsletter = async () => {
|
||||
|
||||
let archiveData: NewsletterData[] = []
|
||||
let archiveData: NewsletterArchiveItem[] = []
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://s3-eu-west-1.amazonaws.com/files.crsend.com/37000/37866/rss/mailings.js',
|
||||
{ cache: "force-cache", next: { revalidate: 3600 }}
|
||||
);
|
||||
const jsContent = await response.text();
|
||||
{ cache: 'force-cache', next: { revalidate: 3600 } },
|
||||
)
|
||||
const jsContent = await response.text()
|
||||
|
||||
// safe (?) alternative to `eval()`
|
||||
const sandbox = new Sandbox();
|
||||
const scope: {cr_archive: NewsletterData[] } = { cr_archive: [] };
|
||||
const exec = sandbox.compile(jsContent);
|
||||
exec(scope).run();
|
||||
|
||||
archiveData = scope.cr_archive.slice(0, 3);
|
||||
const sandbox = new Sandbox()
|
||||
const scope: { cr_archive: NewsletterArchiveItem[] } = { cr_archive: [] }
|
||||
const exec = sandbox.compile(jsContent)
|
||||
exec(scope).run()
|
||||
|
||||
archiveData = scope.cr_archive.slice(0, 3)
|
||||
} catch {
|
||||
console.error("Could not fetch newsletters. Please check PublicationAndNewsletter component")
|
||||
console.error(
|
||||
'Could not fetch newsletters. Please check PublicationAndNewsletter component',
|
||||
)
|
||||
}
|
||||
|
||||
const magazine = await fetchLastMagazine();
|
||||
const magazine_url = magazine && typeof magazine.document === "object" ? magazine.document.url || undefined : undefined;
|
||||
const magazine_cover = magazine && typeof magazine.cover === "object" ? magazine.cover : undefined;
|
||||
const magazine = await fetchLastMagazine()
|
||||
const magazineUrl =
|
||||
magazine && typeof magazine.document === 'object'
|
||||
? magazine.document.url || undefined
|
||||
: undefined
|
||||
const magazineCover =
|
||||
magazine && typeof magazine.cover === 'object' ? magazine.cover : undefined
|
||||
|
||||
return (
|
||||
<Section backgroundColor={"off-white"}>
|
||||
<Container>
|
||||
<Row alignItems={"center"}>
|
||||
<Col>
|
||||
{magazine_url && magazine_cover && magazine_cover.url &&
|
||||
<a href={magazine_url} target={'_blank'}>
|
||||
<Image
|
||||
className={styles.image}
|
||||
src={magazine_cover.url}
|
||||
width={magazine_cover.width || 500}
|
||||
height={magazine_cover.height || 600}
|
||||
alt={'Pfarreimagazin Ausgabe'}
|
||||
unoptimized={true}
|
||||
/>
|
||||
</a>
|
||||
}
|
||||
</Col>
|
||||
<Col>
|
||||
<div className={styles.titleContainer}>
|
||||
<Image src={envelope} alt={'Newsletter icon'} />
|
||||
<Title
|
||||
title={'Newsletter aus dem Bistum'}
|
||||
size={'md'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{archiveData.map((item) => (
|
||||
<NewsletterItem
|
||||
key={item.guid}
|
||||
title={item.title}
|
||||
link={item.link}
|
||||
pubDate={item.pubDate}>
|
||||
</NewsletterItem>
|
||||
))}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
<PublicationAndNewsletterView
|
||||
archiveData={archiveData}
|
||||
magazineUrl={magazineUrl}
|
||||
magazineCover={magazineCover}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
import { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { PublicationAndNewsletterView } from './PublicationAndNewsletterView'
|
||||
|
||||
const meta: Meta<typeof PublicationAndNewsletterView> = {
|
||||
component: PublicationAndNewsletterView,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof PublicationAndNewsletterView>
|
||||
export default meta
|
||||
|
||||
const archiveData = [
|
||||
{
|
||||
guid: '1',
|
||||
title: 'Newsletter aus dem Bistum – März 2026',
|
||||
link: 'https://example.com/newsletter/march',
|
||||
pubDate: '2026-03-01T00:00:00.000Z',
|
||||
},
|
||||
{
|
||||
guid: '2',
|
||||
title: 'Newsletter aus dem Bistum – Februar 2026',
|
||||
link: 'https://example.com/newsletter/february',
|
||||
pubDate: '2026-02-01T00:00:00.000Z',
|
||||
},
|
||||
{
|
||||
guid: '3',
|
||||
title: 'Newsletter aus dem Bistum – Januar 2026',
|
||||
link: 'https://example.com/newsletter/january',
|
||||
pubDate: '2026-01-01T00:00:00.000Z',
|
||||
},
|
||||
]
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
archiveData,
|
||||
magazineUrl: 'https://example.com/magazine.pdf',
|
||||
magazineCover: {
|
||||
url: 'https://placehold.co/500x600/png',
|
||||
width: 500,
|
||||
height: 600,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const NewsletterOnly: Story = {
|
||||
args: {
|
||||
archiveData,
|
||||
},
|
||||
}
|
||||
|
||||
export const MagazineOnly: Story = {
|
||||
args: {
|
||||
archiveData: [],
|
||||
magazineUrl: 'https://example.com/magazine.pdf',
|
||||
magazineCover: {
|
||||
url: 'https://placehold.co/500x600/png',
|
||||
width: 500,
|
||||
height: 600,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const Empty: Story = {
|
||||
args: {
|
||||
archiveData: [],
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { NewsletterItem } from '@/compositions/PublicationAndNewsletter/NewsletterItem'
|
||||
import styles from './styles.module.scss'
|
||||
import Image from 'next/image'
|
||||
import envelope from './envelope.svg'
|
||||
|
||||
export type NewsletterArchiveItem = {
|
||||
guid: string
|
||||
title: string
|
||||
link: string
|
||||
pubDate: string
|
||||
}
|
||||
|
||||
type PublicationAndNewsletterViewProps = {
|
||||
archiveData: NewsletterArchiveItem[]
|
||||
magazineUrl?: string
|
||||
magazineCover?: {
|
||||
url?: string | null
|
||||
width?: number | null
|
||||
height?: number | null
|
||||
}
|
||||
}
|
||||
|
||||
export const PublicationAndNewsletterView = ({
|
||||
archiveData,
|
||||
magazineUrl,
|
||||
magazineCover,
|
||||
}: PublicationAndNewsletterViewProps) => {
|
||||
return (
|
||||
<Section backgroundColor={'off-white'}>
|
||||
<Container>
|
||||
<Row alignItems={'center'}>
|
||||
<Col>
|
||||
{magazineUrl && magazineCover?.url && (
|
||||
<a href={magazineUrl} target={'_blank'}>
|
||||
<Image
|
||||
className={styles.image}
|
||||
src={magazineCover.url}
|
||||
width={magazineCover.width || 500}
|
||||
height={magazineCover.height || 600}
|
||||
alt={'Pfarreimagazin Ausgabe'}
|
||||
unoptimized={true}
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
</Col>
|
||||
<Col>
|
||||
<div className={styles.titleContainer}>
|
||||
<Image src={envelope} alt={'Newsletter icon'} />
|
||||
<Title title={'Newsletter aus dem Bistum'} size={'md'} />
|
||||
</div>
|
||||
|
||||
{archiveData.map((item) => (
|
||||
<NewsletterItem
|
||||
key={item.guid}
|
||||
title={item.title}
|
||||
link={item.link}
|
||||
pubDate={item.pubDate}
|
||||
></NewsletterItem>
|
||||
))}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
import { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { Home } from './Home'
|
||||
|
||||
const meta: Meta<typeof Home> = {
|
||||
component: Home,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof Home>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
events: [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Event 1',
|
||||
date: '2024-12-02T09:21:24Z',
|
||||
location: {
|
||||
id: 'l1',
|
||||
name: "St. Richard",
|
||||
updatedAt: "",
|
||||
createdAt: ""
|
||||
},
|
||||
shortDescription: '',
|
||||
description: "Some descripton",
|
||||
cancelled: false,
|
||||
updatedAt: '2024-12-02T09:21:24Z',
|
||||
createdAt: '2024-12-02T09:21:24Z',
|
||||
isRecurring: false
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Event 2',
|
||||
date: '2024-12-05T09:21:24Z',
|
||||
location: {
|
||||
id: 'l1',
|
||||
name: "St. Richard",
|
||||
updatedAt: "",
|
||||
createdAt: ""
|
||||
},
|
||||
shortDescription: '',
|
||||
description: "",
|
||||
cancelled: false,
|
||||
updatedAt: '2024-12-02T09:21:24Z',
|
||||
createdAt: '2024-12-02T09:21:24Z',
|
||||
isRecurring: false
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Event 2',
|
||||
date: '2024-12-08T09:21:24Z',
|
||||
location: {
|
||||
id: 'l2',
|
||||
name: "St. Hedwig",
|
||||
updatedAt: "",
|
||||
createdAt: ""
|
||||
},
|
||||
shortDescription: '',
|
||||
description: "",
|
||||
cancelled: true,
|
||||
updatedAt: '2024-12-02T09:21:24Z',
|
||||
createdAt: '2024-12-02T09:21:24Z',
|
||||
isRecurring: false
|
||||
},
|
||||
],
|
||||
blog: [
|
||||
{
|
||||
id: 'b1',
|
||||
title: 'Blog 1',
|
||||
content: {
|
||||
excerpt: '',
|
||||
content: []
|
||||
},
|
||||
configuration: {
|
||||
showOnFrontpage: false,
|
||||
},
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
{
|
||||
id: 'b2',
|
||||
title: 'Blog 2',
|
||||
content: {
|
||||
excerpt: '',
|
||||
content: []
|
||||
},
|
||||
configuration: {
|
||||
showOnFrontpage: false,
|
||||
},
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
{
|
||||
id: 'b3',
|
||||
title: 'Blog 3',
|
||||
content: {
|
||||
excerpt: '',
|
||||
content: []
|
||||
},
|
||||
configuration: {
|
||||
showOnFrontpage: false,
|
||||
},
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
],
|
||||
worship: [
|
||||
{
|
||||
id: 'w1',
|
||||
date: '2024-12-02T09:21:24Z',
|
||||
location: {
|
||||
id: 'c1',
|
||||
name: 'St Richard',
|
||||
address: '',
|
||||
createdAt: '',
|
||||
updatedAt: ''
|
||||
},
|
||||
type: 'MASS',
|
||||
cancelled: false,
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
{
|
||||
id: 'w1',
|
||||
date: '2024-12-07T10:00:24Z',
|
||||
location: {
|
||||
id: 'c1',
|
||||
name: 'St Richard',
|
||||
address: '',
|
||||
createdAt: '',
|
||||
updatedAt: ''
|
||||
},
|
||||
type: 'MASS',
|
||||
cancelled: false,
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
],
|
||||
highlights: [],
|
||||
announcements: [
|
||||
{
|
||||
id: "link_1",
|
||||
text: "St. Clara",
|
||||
href: "https://disney.com"
|
||||
},
|
||||
{
|
||||
id: "link_2",
|
||||
text: "St. Anna",
|
||||
href: "https://disney.com"
|
||||
},
|
||||
{
|
||||
id: "link_3",
|
||||
text: "St. Eduard",
|
||||
href: "https://disney.com"
|
||||
}
|
||||
],
|
||||
calendars: [
|
||||
{
|
||||
id: "link_1",
|
||||
text: "St. Clara",
|
||||
href: "https://disney.com"
|
||||
},
|
||||
{
|
||||
id: "link_2",
|
||||
text: "St. Anna",
|
||||
href: "https://disney.com"
|
||||
},
|
||||
{
|
||||
id: "link_3",
|
||||
text: "St. Eduard",
|
||||
href: "https://disney.com"
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
@ -1,198 +1,39 @@
|
|||
import { Blog, Worship, Event, Highlight } from '@/payload-types'
|
||||
import { Banner } from '@/components/Banner/Banner'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Section } from '@/components/Section/Section'
|
||||
import { MainText } from '@/components/MainText/MainText'
|
||||
import { HR } from '@/components/HorizontalRule/HorizontalRule'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { MassGrid } from '@/components/MassTable/MassGrid'
|
||||
import { MassTable } from '@/components/MassTable/MassTable'
|
||||
import { ImageCardSlider } from '@/compositions/ImageCardSlider/ImageCardSlider'
|
||||
import { blogToSlides } from '@/utils/dto/blog'
|
||||
import forest from '@/assets/map.jpg'
|
||||
import { ContentWithSlider } from '@/compositions/ContentWithSlider/ContentWithSlider'
|
||||
import { EventRow } from '@/components/EventRow/EventRow'
|
||||
import { highlightLink } from '@/utils/dto/highlight'
|
||||
import { Events } from '@/compositions/Events/Events'
|
||||
import { transformEvents } from '@/utils/dto/events'
|
||||
import { ContactSection } from '@/compositions/ContactSection/ContactSection'
|
||||
import { CollapsibleImageWithText } from '@/compositions/CollapsibleImageWithText/CollapsibleImageWithText'
|
||||
import { MoreInformation } from '@/pageComponents/Home/MoreInformation'
|
||||
import { Button } from '@/components/Button/Button'
|
||||
import styles from "./styles.module.scss"
|
||||
import moment from 'moment'
|
||||
import { fetchEvents } from '@/fetch/events'
|
||||
import { fetchWorship } from '@/fetch/worship'
|
||||
import { fetchBlogPosts } from '@/fetch/blog'
|
||||
import { fetchHighlights } from '@/fetch/highlights'
|
||||
import { fetchLastAnnouncements } from '@/fetch/announcement'
|
||||
import { fetchLastCalendars } from '@/fetch/calendar'
|
||||
import { perParish } from '@/utils/dto/perParish'
|
||||
import { PublicationAndNewsletter } from '@/compositions/PublicationAndNewsletter/PublicationAndNewsletter'
|
||||
import { Link, PopupButton } from '@/components/PopupButton/PopupButton'
|
||||
import { HomeView } from './HomeView'
|
||||
|
||||
type HomeProps = {
|
||||
events: Event[],
|
||||
worship: Worship[],
|
||||
blog: Blog[],
|
||||
highlights: Highlight[],
|
||||
announcements: Link[],
|
||||
calendars: Link[]
|
||||
}
|
||||
export const Home = async () => {
|
||||
const fromDate = moment().isoWeekday(1).hours(0).minutes(0)
|
||||
const tillDate = moment().isoWeekday(7).hours(23).minutes(59)
|
||||
|
||||
const sortWorship = (worship: Worship[]) => {
|
||||
const map = new Map<string, Worship[]>()
|
||||
|
||||
worship.map(w => {
|
||||
if (typeof w.location === 'object') {
|
||||
const title = w.location.name
|
||||
|
||||
if (map.has(title)) {
|
||||
map.get(title)?.push(w)
|
||||
} else {
|
||||
map.set(title, [w])
|
||||
}
|
||||
}
|
||||
const events = await fetchEvents()
|
||||
const worship = await fetchWorship({
|
||||
fromDate: fromDate.toDate(),
|
||||
tillDate: tillDate.toDate(),
|
||||
})
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
|
||||
export const Home = ({
|
||||
events,
|
||||
worship,
|
||||
blog,
|
||||
highlights,
|
||||
announcements,
|
||||
calendars
|
||||
}: HomeProps) => {
|
||||
const worshipPerLocation = Array.from(
|
||||
sortWorship(worship).entries(),
|
||||
).sort(
|
||||
(a, b) => {
|
||||
const nameA = a[0]
|
||||
const nameB = b[0]
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1
|
||||
}
|
||||
if (nameA > nameB) {
|
||||
return 1
|
||||
}
|
||||
|
||||
// names must be equal
|
||||
return 0
|
||||
},
|
||||
)
|
||||
const blog = await fetchBlogPosts(true)
|
||||
const highlights = await fetchHighlights()
|
||||
const announcements = await fetchLastAnnouncements()
|
||||
const announcementsLinks = announcements ? perParish(announcements) : []
|
||||
const calendars = await fetchLastCalendars()
|
||||
const calendarsLinks = calendars ? perParish(calendars) : []
|
||||
|
||||
return (
|
||||
<>
|
||||
<Banner />
|
||||
|
||||
<Container>
|
||||
<Section>
|
||||
<MainText
|
||||
text={`Willkommen bei der Pfarrei Heilige Drei Könige Nord-Neukölln! Hier begegnen wir einander – spirituell, kulturell, sozial – und gestalten gemeinsam eine lebendige Kirche. Trete ein und entdecke einen Ort, der inspiriert, verbindet und bewegt.`} />
|
||||
</Section>
|
||||
</Container>
|
||||
|
||||
<HR />
|
||||
|
||||
<Container>
|
||||
{blog && blog.length > 0 &&
|
||||
<Section>
|
||||
<Title title={'Aktuelles'} color={"contrast"} />
|
||||
<ImageCardSlider slides={blogToSlides(blog)} />
|
||||
</Section>
|
||||
}
|
||||
</Container>
|
||||
|
||||
<Section paddingBottom={'medium'}>
|
||||
<Title
|
||||
title={'Nächste Gottesdienste'}
|
||||
subtitle={'Komm einfach vorbei!'}
|
||||
color={"contrast"}
|
||||
align={'center'}
|
||||
/>
|
||||
|
||||
<Section padding={'small'}>
|
||||
<MassGrid>
|
||||
{worshipPerLocation.map(value => <MassTable key={value[0]} location={value[0]} masses={value[1]} />)}
|
||||
</MassGrid>
|
||||
</Section>
|
||||
|
||||
<Section padding={'small'}>
|
||||
<div className={styles.center}>
|
||||
|
||||
{ announcements.length > 0 &&
|
||||
<PopupButton
|
||||
text={"Vermeldungen"}
|
||||
title={"Vermeldungen"}
|
||||
links={announcements}
|
||||
schema={"shade"}
|
||||
/>
|
||||
}
|
||||
|
||||
{ calendars.length > 0 &&
|
||||
<PopupButton
|
||||
text={"Liturgischer Kalender"}
|
||||
title={"Kalender"}
|
||||
links={calendars}
|
||||
schema={"shade"}
|
||||
/>
|
||||
}
|
||||
|
||||
<Button
|
||||
href={"/gottesdienst"}
|
||||
size={"md"}
|
||||
>Alle Gottesdienste</Button>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
</Section>
|
||||
|
||||
<CollapsibleImageWithText
|
||||
backgroundColor={'soft'}
|
||||
title={'Über uns'}
|
||||
schema={"base"}
|
||||
text={'Unsere Pfarrei Hl. Drei Könige wurde am 01.01.2020 gegründet. Am 12.01.2020 feierte Erzbischof Dr. Heiner Koch mit den Gemeinden die Gründung in einer feierlichen Hl. Messe in der katholischen Marienschule. Anwesende Gäste waren Bürgermeister Martin Hikel, Christian Nottmeier, der Superintendent des evangelischen Kirchenkreises Neukölln und viele Akteuren aus Kiez und Ökumene. Die Vielfalt der Glaubenswege in unserer Pfarrei sehen wir als Schatz. Wie die drei Weisen aus dem Morgenland wollen wir uns immer wieder neu auf den Weg machen.'}
|
||||
image={forest}
|
||||
content={<MoreInformation />}
|
||||
/>
|
||||
|
||||
<ContentWithSlider slider={<>
|
||||
<Title title={'Aktuelle Highlights'} size={'md'} fontStyle={'sans-serif'} color={'white'} />
|
||||
{highlights.map(highlight => (
|
||||
<EventRow
|
||||
color={'white'}
|
||||
key={highlight.id}
|
||||
date={highlight.date}
|
||||
showDate={false}
|
||||
title={highlight.text}
|
||||
href={highlightLink(highlight)}
|
||||
cancelled={false}
|
||||
/>
|
||||
))}
|
||||
</>}>
|
||||
<Section>
|
||||
<Title
|
||||
color={"contrast"}
|
||||
title={'Veranstaltungen'}
|
||||
/>
|
||||
<Events
|
||||
events={transformEvents(events)}
|
||||
n={6}
|
||||
schema={"contrast"}
|
||||
/>
|
||||
</Section>
|
||||
</ContentWithSlider>
|
||||
|
||||
<PublicationAndNewsletter />
|
||||
|
||||
<ContactSection
|
||||
title={'Kontakt'}
|
||||
description={'Haben Sie Fragen zum Glauben, zu den Sakramenten oder unseren Angeboten? Benötigen Sie Hilfe in einer schwierigen Situation oder möchten Sie einfach Ihre Gedanken mit uns teilen?\n' +
|
||||
'\n' +
|
||||
'Zögern Sie nicht, uns über das Kontaktformular zu schreiben. Wir freuen uns über jede Nachricht und sind gerne für Sie da.'}
|
||||
schema={"base"}
|
||||
toEmail={"kontakt@dreikoenige.berlin"}
|
||||
/>
|
||||
</>
|
||||
|
||||
<HomeView
|
||||
events={events?.docs || []}
|
||||
worship={worship?.docs || []}
|
||||
blog={blog?.docs || []}
|
||||
highlights={highlights?.docs || []}
|
||||
announcements={announcementsLinks}
|
||||
calendars={calendarsLinks}
|
||||
publicationAndNewsletter={<PublicationAndNewsletter />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home;
|
||||
199
src/pageComponents/Home/HomeView.tsx
Normal file
199
src/pageComponents/Home/HomeView.tsx
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
import { Blog, Worship, Event, Highlight } from '@/payload-types'
|
||||
import { Banner } from '@/components/Banner/Banner'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Section } from '@/components/Section/Section'
|
||||
import { MainText } from '@/components/MainText/MainText'
|
||||
import { HR } from '@/components/HorizontalRule/HorizontalRule'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { MassGrid } from '@/components/MassTable/MassGrid'
|
||||
import { MassTable } from '@/components/MassTable/MassTable'
|
||||
import { ImageCardSlider } from '@/compositions/ImageCardSlider/ImageCardSlider'
|
||||
import { blogToSlides } from '@/utils/dto/blog'
|
||||
import forest from '@/assets/map.jpg'
|
||||
import { ContentWithSlider } from '@/compositions/ContentWithSlider/ContentWithSlider'
|
||||
import { EventRow } from '@/components/EventRow/EventRow'
|
||||
import { highlightLink } from '@/utils/dto/highlight'
|
||||
import { Events } from '@/compositions/Events/Events'
|
||||
import { transformEvents } from '@/utils/dto/events'
|
||||
import { ContactSection } from '@/compositions/ContactSection/ContactSection'
|
||||
import { CollapsibleImageWithText } from '@/compositions/CollapsibleImageWithText/CollapsibleImageWithText'
|
||||
import { MoreInformation } from '@/pageComponents/Home/MoreInformation'
|
||||
import { Button } from '@/components/Button/Button'
|
||||
import styles from "./styles.module.scss"
|
||||
import { Link, PopupButton } from '@/components/PopupButton/PopupButton'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
type HomeViewProps = {
|
||||
events: Event[],
|
||||
worship: Worship[],
|
||||
blog: Blog[],
|
||||
highlights: Highlight[],
|
||||
announcements: Link[],
|
||||
calendars: Link[],
|
||||
publicationAndNewsletter?: ReactNode
|
||||
}
|
||||
|
||||
const sortWorship = (worship: Worship[]) => {
|
||||
const map = new Map<string, Worship[]>()
|
||||
|
||||
worship.map(w => {
|
||||
if (typeof w.location === 'object') {
|
||||
const title = w.location.name
|
||||
|
||||
if (map.has(title)) {
|
||||
map.get(title)?.push(w)
|
||||
} else {
|
||||
map.set(title, [w])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
|
||||
export const HomeView = ({
|
||||
events,
|
||||
worship,
|
||||
blog,
|
||||
highlights,
|
||||
announcements,
|
||||
calendars,
|
||||
publicationAndNewsletter,
|
||||
}: HomeViewProps) => {
|
||||
const worshipPerLocation = Array.from(
|
||||
sortWorship(worship).entries(),
|
||||
).sort(
|
||||
(a, b) => {
|
||||
const nameA = a[0]
|
||||
const nameB = b[0]
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1
|
||||
}
|
||||
if (nameA > nameB) {
|
||||
return 1
|
||||
}
|
||||
|
||||
// names must be equal
|
||||
return 0
|
||||
},
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Banner />
|
||||
|
||||
<Container>
|
||||
<Section>
|
||||
<MainText
|
||||
text={`Willkommen bei der Pfarrei Heilige Drei Könige Nord-Neukölln! Hier begegnen wir einander – spirituell, kulturell, sozial – und gestalten gemeinsam eine lebendige Kirche. Trete ein und entdecke einen Ort, der inspiriert, verbindet und bewegt.`} />
|
||||
</Section>
|
||||
</Container>
|
||||
|
||||
<HR />
|
||||
|
||||
<Container>
|
||||
{blog && blog.length > 0 &&
|
||||
<Section>
|
||||
<Title title={'Aktuelles'} color={"contrast"} />
|
||||
<ImageCardSlider slides={blogToSlides(blog)} />
|
||||
</Section>
|
||||
}
|
||||
</Container>
|
||||
|
||||
<Section paddingBottom={'medium'}>
|
||||
<Title
|
||||
title={'Nächste Gottesdienste'}
|
||||
subtitle={'Komm einfach vorbei!'}
|
||||
color={"contrast"}
|
||||
align={'center'}
|
||||
/>
|
||||
|
||||
<Section padding={'small'}>
|
||||
<MassGrid>
|
||||
{worshipPerLocation.map(value => <MassTable key={value[0]} location={value[0]} masses={value[1]} />)}
|
||||
</MassGrid>
|
||||
</Section>
|
||||
|
||||
<Section padding={'small'}>
|
||||
<div className={styles.center}>
|
||||
|
||||
{ announcements.length > 0 &&
|
||||
<PopupButton
|
||||
text={"Vermeldungen"}
|
||||
title={"Vermeldungen"}
|
||||
links={announcements}
|
||||
schema={"shade"}
|
||||
/>
|
||||
}
|
||||
|
||||
{ calendars.length > 0 &&
|
||||
<PopupButton
|
||||
text={"Liturgischer Kalender"}
|
||||
title={"Kalender"}
|
||||
links={calendars}
|
||||
schema={"shade"}
|
||||
/>
|
||||
}
|
||||
|
||||
<Button
|
||||
href={"/gottesdienst"}
|
||||
size={"md"}
|
||||
>Alle Gottesdienste</Button>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
</Section>
|
||||
|
||||
<CollapsibleImageWithText
|
||||
backgroundColor={'soft'}
|
||||
title={'Über uns'}
|
||||
schema={"base"}
|
||||
text={'Unsere Pfarrei Hl. Drei Könige wurde am 01.01.2020 gegründet. Am 12.01.2020 feierte Erzbischof Dr. Heiner Koch mit den Gemeinden die Gründung in einer feierlichen Hl. Messe in der katholischen Marienschule. Anwesende Gäste waren Bürgermeister Martin Hikel, Christian Nottmeier, der Superintendent des evangelischen Kirchenkreises Neukölln und viele Akteuren aus Kiez und Ökumene. Die Vielfalt der Glaubenswege in unserer Pfarrei sehen wir als Schatz. Wie die drei Weisen aus dem Morgenland wollen wir uns immer wieder neu auf den Weg machen.'}
|
||||
image={forest}
|
||||
content={<MoreInformation />}
|
||||
/>
|
||||
|
||||
<ContentWithSlider slider={<>
|
||||
<Title title={'Aktuelle Highlights'} size={'md'} fontStyle={'sans-serif'} color={'white'} />
|
||||
{highlights.map(highlight => (
|
||||
<EventRow
|
||||
color={'white'}
|
||||
key={highlight.id}
|
||||
date={highlight.date}
|
||||
showDate={false}
|
||||
title={highlight.text}
|
||||
href={highlightLink(highlight)}
|
||||
cancelled={false}
|
||||
/>
|
||||
))}
|
||||
</>}>
|
||||
<Section>
|
||||
<Title
|
||||
color={"contrast"}
|
||||
title={'Veranstaltungen'}
|
||||
/>
|
||||
<Events
|
||||
events={transformEvents(events)}
|
||||
n={6}
|
||||
schema={"contrast"}
|
||||
/>
|
||||
</Section>
|
||||
</ContentWithSlider>
|
||||
|
||||
{publicationAndNewsletter}
|
||||
|
||||
<ContactSection
|
||||
title={'Kontakt'}
|
||||
description={'Haben Sie Fragen zum Glauben, zu den Sakramenten oder unseren Angeboten? Benötigen Sie Hilfe in einer schwierigen Situation oder möchten Sie einfach Ihre Gedanken mit uns teilen?\n' +
|
||||
'\n' +
|
||||
'Zögern Sie nicht, uns über das Kontaktformular zu schreiben. Wir freuen uns über jede Nachricht und sind gerne für Sie da.'}
|
||||
schema={"base"}
|
||||
toEmail={"kontakt@dreikoenige.berlin"}
|
||||
/>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ import { Meta, StoryObj } from '@storybook/nextjs-vite'
|
|||
import chris from "../../assets/christophorus.jpeg"
|
||||
import { Parish } from './Parish'
|
||||
import { Menu } from '@/components/Menu/Menu'
|
||||
import { Footer } from '@/compositions/Footer/Footer'
|
||||
import { FooterView } from '@/compositions/Footer/FooterView'
|
||||
|
||||
const meta: Meta<typeof Parish> = {
|
||||
component: Parish,
|
||||
|
|
@ -28,7 +28,18 @@ const meta: Meta<typeof Parish> = {
|
|||
]
|
||||
}}/>
|
||||
<Story />
|
||||
<Footer />
|
||||
<FooterView
|
||||
prayers={['Herr, gib uns deinen Frieden.']}
|
||||
footer={{
|
||||
id: 'mock-footer',
|
||||
groups: [
|
||||
{
|
||||
title: 'Pfarrei',
|
||||
links: [{ label: 'Kontakt', href: '/kontakt' }],
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -27,26 +27,20 @@ export const WithResults: Story = {
|
|||
results: [
|
||||
makeResult('1', 'Sonntagsgottesdienst', {
|
||||
relationTo: 'pages',
|
||||
value: {
|
||||
id: 'p1',
|
||||
slug: 'gottesdienst',
|
||||
} as Search['doc']['value'],
|
||||
}),
|
||||
value: { id: 'p1', slug: 'gottesdienst' },
|
||||
} as unknown as Search['doc']),
|
||||
makeResult('2', 'Ostern 2026 – Liturgische Feier', {
|
||||
relationTo: 'event',
|
||||
value: { id: 'e1' } as Search['doc']['value'],
|
||||
}),
|
||||
value: { id: 'e1' },
|
||||
} as unknown as Search['doc']),
|
||||
makeResult('3', 'Ministrantengruppe', {
|
||||
relationTo: 'group',
|
||||
value: {
|
||||
id: 'g1',
|
||||
slug: 'ministranten',
|
||||
} as Search['doc']['value'],
|
||||
}),
|
||||
value: { id: 'g1', slug: 'ministranten' },
|
||||
} as unknown as Search['doc']),
|
||||
makeResult('4', 'Rundbrief Januar', {
|
||||
relationTo: 'blog',
|
||||
value: { id: 'b1' } as Search['doc']['value'],
|
||||
}),
|
||||
value: { id: 'b1' },
|
||||
} as unknown as Search['doc']),
|
||||
],
|
||||
},
|
||||
}
|
||||
|
|
@ -63,4 +57,4 @@ export const EmptyQuery: Story = {
|
|||
query: '',
|
||||
results: [],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue