feature: new

This commit is contained in:
Benno Tielen 2024-12-02 10:50:32 +01:00
parent 82612662aa
commit dd4974ec28
33 changed files with 2103 additions and 1766 deletions

View file

@ -1,2 +1,2 @@
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
DATABASE_URI=mongodb://127.0.0.1/dreikoenige
PAYLOAD_SECRET=YOUR_SECRET_HERE

View file

@ -5,7 +5,7 @@ const preview: Preview = {
decorators: [
(Story) => {
return (
<div className={defaultFont.className}>
<div className={defaultFont.className} style={{fontSize: 20}}>
<Story />
</div>
)

View file

@ -1,42 +1,39 @@
# Payload Blank Template
# Heilige Drei Könige Website
This is the repository for the Heilige Drei Könige Catholic Church website, built using
Payload CMS v3, NextJS, React and MongoDB.
A blank template for [Payload](https://github.com/payloadcms/payload) to help you get up and running quickly. This repo may have been created by running `npx create-payload-app@latest` and selecting the "blank" template or by cloning this template on [Payload Cloud](https://payloadcms.com/new/clone/blank).
## Getting Started
See the official [Examples Directory](https://github.com/payloadcms/payload/tree/main/examples) for details on how to use Payload in a variety of different ways.
### Prerequisites
- Node.js and npm: Make sure you have Node.js and npm installed on your machine.
- MongoDB: You'll need a MongoDB database to store the website data.
## Development
To spin up the project locally, follow these steps:
### MongoDB
1. First clone the repo
1. Then `cd YOUR_PROJECT_REPO && cp .env.example .env`
1. Next `yarn && yarn dev` (or `docker-compose up`, see [Docker](#docker))
1. Now `open http://localhost:3000/admin` to access the admin panel
1. Create your first admin user using the form on the page
If you don't have docker on system installed, please
follow the instructions for your operating system on the Docker website.
That's it! Changes made in `./src` will be reflected in your app.
To pull the MongoDB docker image:
```bash
docker pull mongodb/mongodb-community-server:latest
```
### Docker
To Run the image as a Container
```bash
docker run --name mongodb -p 27017:27017 -d mongodb/mongodb-community-server:latest
```
Alternatively, you can use [Docker](https://www.docker.com) to spin up this project locally. To do so, follow these steps:
### Environment variables
1. Follow [steps 1 and 2 from above](#development), the docker-compose file will automatically use the `.env` file in your project root
1. Next run `docker-compose up`
1. Follow [steps 4 and 5 from above](#development) to login and create your first admin user
Please set the environment variables in the `.env` file
That's it! The Docker instance will help you get up and running quickly while also standardizing the development environment across your teams.
```bash
cp .env.example .env
```
## Production
### Development server
To run Payload in production, you need to build and serve the Admin panel. To do so, follow these steps:
1. First invoke the `payload build` script by running `yarn build` or `npm run build` in your project root. This creates a `./build` directory with a production-ready admin bundle.
1. Then run `yarn serve` or `npm run serve` to run Node in production and serve Payload from the `./build` directory.
### Deployment
The easiest way to deploy your project is to use [Payload Cloud](https://payloadcms.com/new/import), a one-click hosting solution to deploy production-ready instances of your Payload apps directly from your GitHub repo. You can also deploy your app manually, check out the [deployment documentation](https://payloadcms.com/docs/production/deployment) for full details.
## Questions
If you have any issues or questions, reach out to us on [Discord](https://discord.com/invite/payload) or start a [GitHub discussion](https://github.com/payloadcms/payload/discussions).
```bash
npm run dev
```

View file

@ -17,16 +17,16 @@
"chromatic": "npx chromatic --project-token=chpt_70d6a2e05af185a"
},
"dependencies": {
"@payloadcms/db-mongodb": "beta",
"@payloadcms/next": "beta",
"@payloadcms/plugin-cloud": "beta",
"@payloadcms/richtext-lexical": "beta",
"@payloadcms/db-mongodb": "^3.2.1",
"@payloadcms/next": "^3.2.1",
"@payloadcms/plugin-cloud": "^3.0.2",
"@payloadcms/richtext-lexical": "^3.2.1",
"classnames": "^2.5.1",
"cross-env": "^7.0.3",
"graphql": "^16.8.1",
"mapbox-gl": "^3.5.2",
"next": "15.0.0",
"payload": "beta",
"payload": "^3.2.1",
"qs-esm": "^7.0.2",
"react": "19.0.0-rc-65a56d0e-20241020",
"react-dom": "19.0.0-rc-65a56d0e-20241020",

View file

@ -38,7 +38,7 @@ export default async function BlogPage({ params }: { params: Promise<{id: string
<>
<Section paddingBottom={"small"}>
<Container>
<Title title={data.title}></Title>
<Title title={data.title} color={"contrast"}></Title>
<strong><TextDiv text={data.excerpt} /></strong>
<p className={styles.published}>
Publiziert am {readableDateTime(data.createdAt)}
@ -68,7 +68,7 @@ export default async function BlogPage({ params }: { params: Promise<{id: string
return (
<Container key={item.id}>
<Section padding={"medium"}>
<Button size={"lg"} href={item.file.url || "notfound"}>{item.button}</Button>
<Button size={"lg"} href={item.file.url || "notfound"} schema={"contrast"}>{item.button}</Button>
</Section>
</Container>
)
@ -76,7 +76,12 @@ export default async function BlogPage({ params }: { params: Promise<{id: string
if (item.blockType === "contactform") {
return (
<ContactSection key={item.id} title={item.title} description={item.description} />
<ContactSection
key={item.id}
title={item.title}
description={item.description}
backgroundColor={"off-white"}
/>
)
}

View file

@ -62,6 +62,7 @@ export default async function GroupPage({ params }: { params: Promise<{slug: str
<Title title={"Veranstaltungen"} size={"md"} />
<Events events={transformEvents(events.docs)} n={3} />
</Container>
<Section></Section>
</Section>
}

View file

@ -28,8 +28,8 @@ export default function RootLayout({
text: 'Gemeinschaft finden',
megaMenu: {
text: {
quote: '',
source: ''
quote: '„Denn wo zwei oder drei in meinem Namen versammelt sind, da bin ich mitten unter ihnen.“',
source: 'Matt 18,20'
},
groups: [
{
@ -58,7 +58,7 @@ export default function RootLayout({
{
title: "Kathoccino",
description: "Begegnung mit Gott",
href: "https://"
href: "/gruppe/kathocchino"
},
{
title: "Credo & Agape",
@ -78,38 +78,28 @@ export default function RootLayout({
]
},
{
title: "Aktivitaten",
title: "Musik",
items: [
{
title: "Kochen",
description: "Begegnung mit Gott",
title: "Little Richards",
description: "Der Hausband von St. Richard",
href: "https://"
},
{
title: "Lernen",
description: "Gebet der Meditation",
title: "Kindergruppe",
description: "Jeden Freitag singen und spielen",
href: "https://"
},
{
title: "Wandern",
description: "Stille Begegnung mit Gott",
href: "https://"
},
{
title: "Singen",
description: "Dank, Ehre und Freude",
href: "https://"
},
}
]
}
]
}
},
{
text: 'Glauben lauben',
text: 'Glauben feiern',
megaMenu: {
text: {
quote: '',
quote: 'Innehalten, Be- trachten, Em -pfinden, Besinnen, anders weitermachen',
source: ''
},
groups: [
@ -159,7 +149,7 @@ export default function RootLayout({
{
title: "Rosenkranz",
description: "Gebet der Meditation",
href: "https://"
href: "/gruppe/rosenkranz"
},
{
title: "Anbetung",
@ -176,6 +166,62 @@ export default function RootLayout({
]
}
},
{
text: 'Liebe leben',
megaMenu: {
text: {
quote: '',
source: ''
},
groups: [
{
title: "Ehrenamt",
items: [
{
href: 'http://',
title: 'Wärmestube',
description: 'Kälteschutz für Bedurftigen',
},
{
href: 'http://',
title: 'Essen ist Fertig',
description: 'Essensausgabe Neukölln',
},
{
href: 'http://',
title: 'Anpacken',
description: 'Reinigung, liturgischen Dienst & weiter',
},
]
},
{
title: "Aktivitaten",
items: [
{
title: "Kochen",
description: "Begegnung mit Gott",
href: "https://"
},
{
title: "Lernen",
description: "Gebet der Meditation",
href: "https://"
},
{
title: "Wandern",
description: "Stille Begegnung mit Gott",
href: "https://"
},
{
title: "Singen",
description: "Dank, Ehre und Freude",
href: "https://"
},
]
}
]
}
},
{
text: 'Kontakt',
href: '/kontakt'

View file

@ -1,135 +1,26 @@
import { Banner } from '@/components/Banner/Banner'
import { Section } from '@/components/Section/Section'
import { MainText } from '@/components/MainText/MainText'
import { Title } from '@/components/Title/Title'
import { ImageWithText } from '@/compositions/ImageWithText/ImageWithText'
import { Container } from '@/components/Container/Container'
import { ContactSection } from '@/compositions/ContactSection/ContactSection'
import { ContentWithSlider } from '@/compositions/ContentWithSlider/ContentWithSlider'
import { Events } from '@/compositions/Events/Events'
import { fetchEvents } from '@/fetch/events'
import forest from '../assets/forest.jpeg'
import { fetchWorship } from '@/fetch/worship'
import { Worship } from '@/payload-types'
import { MassTable } from '@/components/MassTable/MassTable'
import { transformEvents } from '@/utils/dto/events'
import { fetchBlog } from '@/fetch/blog'
import { ImageCardSlider } from '@/compositions/ImageCardSlider/ImageCardSlider'
import { blogToSlides } from '@/utils/dto/blog'
import { fetchHighlights } from '@/fetch/highlights'
import { EventRow } from '@/components/EventRow/EventRow'
import { highlightLink } from '@/utils/dto/highlight'
import { MassRow } from '@/components/MassTable/MassRow'
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
}
import { Home } from '@/pageComponents/Home/Home'
export const dynamic = 'force-dynamic'
export default async function Home() {
export default async function HomePage() {
const events = await fetchEvents(undefined)
const worship = await fetchWorship()
const worshipPerLocation = Array.from(
sortWorship(worship?.docs || []).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 fetchBlog()
const highlights = await fetchHighlights()
return (
<>
<Banner />
<Container>
<Section>
<MainText
text={'Wir begrüßen Sie herzlich in unserer Pfarrei Hl. Drei Könige und im bunten Neukölln mit einer Vielfalt von Kulturen und Nationalitäten. \n' +
'Wie die drei Weisen aus dem Morgenland wollen wir uns immer wieder neu auf den Weg machen.'} />
</Section>
<Section paddingBottom={'medium'}>
<Title
title={'Unsere Gottesdiensten'}
subtitle={'Komm einfach vorbei!'}
align={'center'}
/>
<Section padding={'small'}>
<MassRow>
{worshipPerLocation.map(value => <MassTable key={value[0]} location={value[0]} masses={value[1]} />)}
</MassRow>
</Section>
</Section>
{blog && blog.docs.length > 0 &&
<Section>
<Title title={'Aktuelles'} />
<ImageCardSlider slides={blogToSlides(blog.docs)} />
</Section>
}
</Container>
{<ImageWithText backgroundColor={'soft'} title={'Über uns'}
text={'Wir begrüßen Sie herzlich in unserer Pfarrei Hl. Drei Könige und im bunten Neukölln mit einer Vielfalt von Kulturen und Nationalitäten.\n' +
'\n' +
'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 vielen 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} />}
<ContentWithSlider slider={<>
<Title title={'Akutelle Highlights'} size={'md'} fontStyle={'sans-serif'} color={'white'} />
{highlights?.docs.map(highlight => (
<EventRow
color={'white'}
key={highlight.id}
date={highlight.date}
title={highlight.text}
href={highlightLink(highlight)}
cancelled={false}
/>
))}
</>}>
<Section>
<Title title={'Veranstaltungen'} />
<Events events={transformEvents(events?.docs || [])} n={6} />
</Section>
</ContentWithSlider>
<ContactSection title={'Kontakt'}
description={'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec molestie ligula. Maecenas sollicitudin molestie velit id ultricies. Nulla luctus eleifend est, et hendrerit nunc pretium in. Nullam leo tortor, tincidunt in sodales dapibus, faucibus vel lacus. Nunc ornare lacus eu dui consequat, fermentum tincidunt felis blandit. Vivamus a turpis eros. Donec faucibus mi in magna cursus maximus. Duis ac elit posuere, bibendum nunc vel, consectetur neque. Aliquam non bibendum quam. Nulla facilisi. Vivamus eu iaculis felis. Donec elit augue, pretium eget pretium ullamcorper, vestibulum eu lorem. Praesent gravida condimentum tortor, in dignissim mauris elementum quis. Morbi a venenatis odio. Vivamus quis magna eget elit pellentesque elementum. Nulla facilisi.'} />
</>
<Home
schema={"contrast"}
events={events?.docs || []}
worship={worship?.docs || []}
blog={blog?.docs || []}
highlights={highlights?.docs || []}
/>
)
}

View file

@ -19,3 +19,10 @@ export const Right: Story = {
direction: "right"
},
}
export const Contrast: Story = {
args: {
direction: "left",
schema: 'contrast'
},
}

View file

@ -1,9 +1,10 @@
type ArrowProps = {
schema?: 'base' | 'contrast',
direction: 'left' | 'right',
onClick?: () => void
}
export const Arrow = ({ direction, onClick }: ArrowProps) => {
export const Arrow = ({ direction, onClick, schema = "base" }: ArrowProps) => {
return (
<svg
width="21"
@ -12,7 +13,7 @@ export const Arrow = ({ direction, onClick }: ArrowProps) => {
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={{ transform: `rotate(${direction === 'left' ? 0 : 180}deg)` }}
stroke="#426156"
stroke={schema === "base" ? '#426156' : '#7D1224'}
onClick={onClick}
>
<path d="M19 1.53406L2.68974 27.0243C2.26927 27.6814 2.26927 28.5231 2.68974 29.1802L19 54.6704"

View file

@ -2,7 +2,7 @@ import { Meta, StoryObj } from "@storybook/react"
import { Button } from './Button'
const meta: Meta<typeof Button> = {
component: Button
component: Button,
}
type Story = StoryObj<typeof Button>
@ -15,9 +15,25 @@ export const Large: Story = {
}
}
export const Contrast: Story = {
args: {
children: 'Contrast',
schema: "contrast",
size: "lg"
}
}
export const Medium: Story = {
args: {
children: 'Weiterlesen',
size: "md"
}
}
export const Link: Story = {
args: {
children: 'Disney',
size: "lg",
href: 'https://disney.com'
}
}

View file

@ -3,6 +3,7 @@ import classNames from 'classnames'
type ButtonProps = {
size: 'lg' | 'md'
schema?: 'base' | 'contrast'
type?: "button" | "submit" | "reset",
href?: string,
children: React.ReactNode,
@ -12,6 +13,7 @@ type ButtonProps = {
export function Button(
{
type = "button",
schema = 'base',
size,
children,
onClick,
@ -24,6 +26,8 @@ export function Button(
onClick={onClick}
className={classNames({
[styles.button]: true,
[styles.base]: schema == 'base',
[styles.contrast]: schema == 'contrast',
[styles.lg]: size === 'lg',
[styles.md]: size === 'md',
})}
@ -38,6 +42,8 @@ export function Button(
onClick={onClick}
className={classNames({
[styles.button]: true,
[styles.base]: schema == 'base',
[styles.contrast]: schema == 'contrast',
[styles.lg]: size === 'lg',
[styles.md]: size === 'md',
})}

View file

@ -1,7 +1,7 @@
@import 'template.scss';
.button {
background: $shade1;
font-family: inherit;
color: #ffffff;
border-radius: $border-radius;
text-align: center;
@ -14,8 +14,20 @@
display: inline-block;
}
.button:hover {
background: $base-color;
.base {
background-color: $shade1;
}
.base:hover {
background-color: $base-color;
}
.contrast {
background-color: $contrast-color
}
.contrast:hover {
background-color: $contrast-shade1
}
.lg {

View file

@ -38,6 +38,17 @@ export const CancelledEvent: Story = {
},
}
export const Contrast: Story = {
args: {
date: '2024-03-24T15:00:00+01:00',
title: 'Osternacht',
href: 'https://www.link_to_event.com',
location: "St. Richard",
cancelled: false,
color: "contrast"
},
}
export const DarkBackground: Story = {
args: {
date: '2024-01-06T15:00:00+01:00',

View file

@ -10,7 +10,7 @@ export type EventRowProps = {
href?: string,
location?: string,
cancelled: boolean
color?: "base" | "white"
color?: "base" | "white" | "contrast"
}
/**
@ -50,6 +50,7 @@ export const EventRow = ({date, title, location, cancelled, href, color = "base"
<div className={classNames({
[styles.day]: true,
[styles.dayBase]: color === "base",
[styles.dayContrast]: color === "contrast",
[styles.dayWhite]: color === "white"
})}>
{day} <br />

View file

@ -13,6 +13,10 @@
color: $base-color;
}
.dayContrast {
color: $contrast-color;
}
.dayWhite{
color: $shade3;
}
@ -58,6 +62,10 @@
color: $shade2;
}
.container:hover .dayContrast {
color: $contrast-shade1;
}
@media screen and (max-width: 576px) {
.day {
margin-left: 15px;

View file

@ -20,7 +20,7 @@ export const MassTable = ({ location, masses }: MassTableProps) => {
</div>
<div className={styles.church}>
<ChurchCard church={church(location)} backgroundColor={"#E3E9E8"} width={200} />
<ChurchCard church={church(location)} backgroundColor={"#ffffff"} width={200} />
</div>
{masses.map((mass) => (

View file

@ -18,7 +18,6 @@
font-size: 22px;
font-weight: bold;
margin-bottom: 10px;
color: $shade1;
}
.cancelled {

View file

@ -9,5 +9,13 @@ type Story = StoryObj<typeof ContactForm>;
export default meta
export const Default: Story = {
args: {},
args: {
schema: 'base'
},
}
export const Schema: Story = {
args: {
schema: 'contrast'
}
}

View file

@ -3,7 +3,11 @@ import { Button } from '@/components/Button/Button'
import styles from "./styles.module.scss"
import classNames from 'classnames'
export const ContactForm = () => {
type ContactFormProps = {
schema?: "base" | "contrast"
}
export const ContactForm = ({schema}: ContactFormProps) => {
return (
<form>
<div className={classNames(styles.row, styles.firsRow)}>
@ -17,7 +21,7 @@ export const ContactForm = () => {
<Input name={"message"} type={"textarea"} placeholder={"Ihre Nachricht"} />
</div>
<div className={styles.row}>
<Button size={"lg"} type={"submit"}>Abschicken</Button>
<Button size={"lg"} type={"submit"} schema={schema}>Abschicken</Button>
</div>
</form>
)

View file

@ -9,5 +9,8 @@ type Story = StoryObj<typeof ContactSection>;
export default meta
export const Default: Story = {
args: {},
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.'
},
}

View file

@ -8,21 +8,23 @@ import { TextDiv } from '@/components/Text/TextDiv'
type ContactSectionProps = {
title: string,
description: string
description: string,
backgroundColor?: 'off-white'
schema?: 'base' | 'contrast'
}
export const ContactSection = ({title, description}: ContactSectionProps) => {
export const ContactSection = ({title, description, schema, backgroundColor}: ContactSectionProps) => {
return (
<Section backgroundColor={"off-white"}>
<Section backgroundColor={backgroundColor}>
<Container>
<Row>
<Col>
<Title title={title} size={"md"} />
<Title title={title} size={"md"} color={schema}/>
<TextDiv text={description} />
</Col>
<Col>
<ContactForm />
<ContactForm schema={schema}/>
</Col>
</Row>
</Container>

View file

@ -8,59 +8,69 @@ const meta: Meta<typeof Events> = {
type Story = StoryObj<typeof Events>;
export default meta
const events = [
{
title: "Event 1",
date: "2024-01-06T15:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 2",
date: "2024-01-08T19:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 3",
date: "2024-01-09T12:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 4",
date: "2024-01-12T10:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 5",
date: "2024-01-23T09:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 6",
date: "2024-02-01T14:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 7",
date: "2024-03-12T18:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
];
export const Default: Story = {
args: {
events: [
{
title: "Event 1",
date: "2024-01-06T15:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 2",
date: "2024-01-08T19:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 3",
date: "2024-01-09T12:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 4",
date: "2024-01-12T10:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 5",
date: "2024-01-23T09:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 6",
date: "2024-02-01T14:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
{
title: "Event 7",
date: "2024-03-12T18:00:00+01:00",
location: "St Richard",
cancelled: false,
href: "https://some_url"
},
],
events,
n: 3
},
}
export const Contrast: Story = {
args: {
schema: 'contrast',
events,
n: 3
},
}

View file

@ -14,9 +14,11 @@ type EventsProps = {
* page
*/
n: number,
schema?: 'base' | 'contrast'
}
export const Events = ({ events, n }: EventsProps) => {
export const Events = ({ events, n, schema = 'base' }: EventsProps) => {
const [page, setPage] = useState<number>(0)
const eventsPerPage = useMemo(() => {
@ -25,17 +27,21 @@ export const Events = ({ events, n }: EventsProps) => {
return (
<>
{
eventsPerPage.map(event =>
<EventRow
key={event.href}
date={event.date}
title={event.title}
href={event.href}
location={event.location}
cancelled={event.cancelled}
/>,
)}
<div>
{
eventsPerPage.map(event =>
<EventRow
key={event.href}
date={event.date}
title={event.title}
href={event.href}
location={event.location}
cancelled={event.cancelled}
color={schema}
/>,
)}
</div>
<div className={styles.buttons}>
<button

View file

@ -52,6 +52,7 @@ export const ImageCardSlider = ({slides}: ImageCardSliderProps) => {
})}>
<Arrow
direction={"left"}
schema={"contrast"}
onClick={() => setPage(page - 1)}
/>
</div>
@ -70,6 +71,7 @@ export const ImageCardSlider = ({slides}: ImageCardSliderProps) => {
})}>
<Arrow
direction={"right"}
schema={"contrast"}
onClick={() => setPage(page + 1)}
/>
</div>

View file

@ -15,11 +15,11 @@ export const AboutUs: Story = {
args: {
image: forest,
backgroundColor: "soft",
schema: 'contrast',
title: 'Über uns',
text: 'Wir begrüßen Sie herzlich in unserer Pfarrei Hl. Drei Könige und im bunten Neukölln mit einer Vielfalt von Kulturen und Nationalitäten.\n' +
'\n' +
'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 vielen 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.',
link: <Button size={"lg"}>Mehr erfahren...</Button>
},
}

View file

@ -13,9 +13,10 @@ type ImageWithTextProps = {
image: StaticImageData | string,
text: string
link?: React.ReactNode
schema?: 'base' | 'contrast'
}
export const ImageWithText = ({backgroundColor, title, image, text, link}: ImageWithTextProps) => {
export const ImageWithText = ({backgroundColor, title, image, text, link, schema = "base"}: ImageWithTextProps) => {
return (
<Section backgroundColor={backgroundColor}>
<Container>
@ -24,7 +25,7 @@ export const ImageWithText = ({backgroundColor, title, image, text, link}: Image
<Image className={styles.image} width={800} height={800} src={image} objectFit={"cover"} alt={""} />
</div>
<div className={styles.col}>
<Title title={title} size={"lg"} />
<Title title={title} size={"lg"} color={schema} />
<Image className={styles.imageMobile} width={500} height={500} src={image} objectFit={"cover"} alt={""} />

View file

@ -43,7 +43,8 @@ export async function fetchEvents(parishId: string | undefined, groupId?: string
select: {
location: true,
date: true,
title: true
title: true,
cancelled: true
}
},
{ addQueryPrefix: true },

View file

@ -1,198 +1,136 @@
import { Meta, StoryObj } from '@storybook/react'
import { Home } from './Home'
import { Menu } from '@/components/Menu/Menu'
import { Footer } from '@/compositions/Footer/Footer'
const meta: Meta<typeof Home> = {
component: Home,
decorators: [
(Story) => (
<>
<Menu menu={{
leftItems: [
{
text: 'Home',
href: '/'
},
{
text: 'Gemeinschaft finden',
megaMenu: {
text: {
quote: '',
source: ''
},
groups: [
{
title: "Gemeinden",
items: [
{
title: "St. Richard",
description: "Mehr informationen",
href: "/gemeinde/st-richard"
},
{
title: "St. Christophorus",
description: "Mehr informationen",
href: "/gemeinde/st-christophorus"
},
{
title: "St. Clara",
description: "Mehr informationen",
href: "/gemeinde/st-clara"
},
]
},
{
title: "Gruppen",
items: [
{
title: "Kathoccino",
description: "Begegnung mit Gott",
href: "https://"
},
{
title: "Credo & Agape",
description: "Gebet der Meditation",
href: "https://"
},
{
title: "Mädchengruppe",
description: "Stille Begegnung mit Gott",
href: "https://"
},
{
title: "Alphakurs",
description: "Dank, Ehre und Freude",
href: "https://"
},
]
},
{
title: "Aktivitaten",
items: [
{
title: "Kochen",
description: "Begegnung mit Gott",
href: "https://"
},
{
title: "Lernen",
description: "Gebet der Meditation",
href: "https://"
},
{
title: "Wandern",
description: "Stille Begegnung mit Gott",
href: "https://"
},
{
title: "Singen",
description: "Dank, Ehre und Freude",
href: "https://"
},
]
}
]
}
},
{
text: 'Glauben lauben',
megaMenu: {
text: {
quote: '',
source: ''
},
groups: [
{
title: "Sakramenten",
items: [
{
title: "Taufe",
description: "Neues Leben in Christus",
href: "/sakramente/taufe"
},
{
title: "Eucharistie",
description: "Gemeinschaft durch Brot und Wein",
href: "/sakramente/eucharistie"
},
{
title: "Firmung",
description: "Stärkung im Heiligen Geist",
href: "/sakramente/firmung"
},
{
title: "Ehe",
description: "Bund in Liebe, Treue",
href: "/sakramente/ehe"
},
{
title: "Beichte",
description: "Sündenbekenntnis, Vergebung und Neuanfang mit Gottes Gnade",
href: "/sakramente/beichte"
},
{
title: "Krankensalbung",
description: "Stärkung und Gottes Beistand",
href: "/sakramente/krankensalbung"
}
]
},
{
title: "Gebet",
items: [
{
title: "Gottesdienste",
description: "Begegnung mit Gott",
href: "https://"
},
{
title: "Rosenkranz",
description: "Gebet der Meditation",
href: "https://"
},
{
title: "Anbetung",
description: "Stille Begegnung mit Gott",
href: "https://"
},
{
title: "Lobpreis",
description: "Dank, Ehre und Freude",
href: "https://"
},
]
}
]
}
},
{
text: 'Kontakt',
href: '/kontakt'
}
],
rightItems: [
{
text: 'Mithelfen',
href: '/mithelfen',
},
{
text: 'Neu hier?',
href: '/ich-bin-neu',
display: "button"
}
]
}}/>
<Story />
<Footer />
</>
)
]
}
type Story = StoryObj<typeof Home>;
export default meta
export const Default: Story = {
args: {},
args: {
schema: 'base',
events: [
{
id: '1',
title: 'Event 1',
date: '2024-12-02T09:21:24Z',
location: 'St. Richard',
shortDescription: '',
description: {
root: {
type: '',
children: [],
direction: null,
format: '',
indent: 0,
version: 0,
},
},
cancelled: false,
updatedAt: '2024-12-02T09:21:24Z',
createdAt: '2024-12-02T09:21:24Z',
},
{
id: '2',
title: 'Event 2',
date: '2024-12-05T09:21:24Z',
location: 'St. Clara',
shortDescription: '',
description: {
root: {
type: '',
children: [],
direction: null,
format: '',
indent: 0,
version: 0,
},
},
cancelled: false,
updatedAt: '2024-12-02T09:21:24Z',
createdAt: '2024-12-02T09:21:24Z',
},
{
id: '2',
title: 'Event 2',
date: '2024-12-08T09:21:24Z',
location: 'St. Hedwig',
shortDescription: '',
description: {
root: {
type: '',
children: [],
direction: null,
format: '',
indent: 0,
version: 0,
},
},
cancelled: true,
updatedAt: '2024-12-02T09:21:24Z',
createdAt: '2024-12-02T09:21:24Z',
},
],
blog: [
{
id: 'b1',
title: 'Blog 1',
excerpt: '',
content: [],
updatedAt: '',
createdAt: '',
},
{
id: 'b2',
title: 'Blog 2',
excerpt: '',
content: [],
updatedAt: '',
createdAt: '',
},
{
id: 'b3',
title: 'Blog 3',
excerpt: '',
content: [],
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: [],
},
}

View file

@ -1,70 +1,156 @@
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 { MassRow } from '@/components/MassTable/MassRow'
import { MassTable } from '@/components/MassTable/MassTable'
import { ImageCardSlider } from '@/compositions/ImageCardSlider/ImageCardSlider'
import monst from '@/app/mons.jpg'
import candle from '@/app/candle.png'
import bread from '@/app/bread.jpg'
import forest from "../../assets/forest.jpeg"
import { ContentWithSlider } from '@/compositions/ContentWithSlider/ContentWithSlider'
import { ContactSection } from '@/compositions/ContactSection/ContactSection'
import { blogToSlides } from '@/utils/dto/blog'
import { ImageWithText } from '@/compositions/ImageWithText/ImageWithText'
import forest from '@/assets/forest.jpeg'
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'
type HomeProps = {
schema: 'base' | 'contrast',
events: Event[],
worship: Worship[],
blog: Blog[],
highlights: Highlight[],
}
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 Home = ({
schema,
events,
worship,
blog,
highlights
}: 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
},
)
export const Home = () => {
return (
<>
<Banner/>
<Banner />
<Container>
<Section>
<MainText text={"Wir begrüßen Sie herzlich in unserer Pfarrei Hl. Drei Könige und im bunten Neukölln mit einer Vielfalt von Kulturen und Nationalitäten. \n" +
"Wie die drei Weisen aus dem Morgenland wollen wir uns immer wieder neu auf den Weg machen."} />
</Section>
<Section>
<Title title={"Aktuelles"} />
<ImageCardSlider slides={[
{
id: "id1",
src: monst,
title: "Anbetung in Oktober",
href: "https://somelink"
},
{
id: "id2",
src: candle,
title: "Allerseelen",
href: "https://somelink"
},
{
id: "id3",
src: bread,
title: "Erntedankfest",
href: "https://somelink"
}
]} />
<MainText
text={'Wir begrüßen Sie herzlich in unserer Pfarrei Hl. Drei Könige und im bunten Neukölln mit einer Vielfalt von Kulturen und Nationalitäten. \n' +
'Wie die drei Weisen aus dem Morgenland wollen wir uns immer wieder neu auf den Weg machen.'} />
</Section>
</Container>
<ContentWithSlider slider={<>
<Title title={"Akutelle Highlights"} size={"md"} fontStyle={"sans-serif"} color={"white"} />
</>}>
<Container position={"right"}>
<Section>
<Title title={"Veranstaltungen"} />
<HR />
<Container>
<Section paddingBottom={'medium'}>
<Title
title={'Nächste Gottesdiensten'}
subtitle={'Komm einfach vorbei!'}
color={schema}
align={'center'}
/>
<Section padding={'small'}>
<MassRow>
{worshipPerLocation.map(value => <MassTable key={value[0]} location={value[0]} masses={value[1]} />)}
</MassRow>
</Section>
</Container>
</Section>
{blog && blog.length > 0 &&
<Section>
<Title title={'Aktuelles'} color={schema} />
<ImageCardSlider slides={blogToSlides(blog)} />
</Section>
}
</Container>
{<ImageWithText
backgroundColor={'soft'}
title={'Über uns'}
schema={schema}
text={'Wir begrüßen Sie herzlich in unserer Pfarrei Hl. Drei Könige und im bunten Neukölln mit einer Vielfalt von Kulturen und Nationalitäten.\n' +
'\n' +
'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 vielen 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}
/>}
<ContentWithSlider slider={<>
<Title title={'Akutelle Highlights'} size={'md'} fontStyle={'sans-serif'} color={'white'} />
{highlights.map(highlight => (
<EventRow
color={'white'}
key={highlight.id}
date={highlight.date}
title={highlight.text}
href={highlightLink(highlight)}
cancelled={false}
/>
))}
</>}>
<Section>
<Title
color={schema}
title={'Veranstaltungen'}
/>
<Events events={transformEvents(events)} n={6} />
</Section>
</ContentWithSlider>
<ImageWithText
image={forest}
title={"Über uns"}
text={"yolo"}
backgroundColor={"soft"}
<ContactSection
title={'Kontakt'}
description={'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec molestie ligula. Maecenas sollicitudin molestie velit id ultricies. Nulla luctus eleifend est, et hendrerit nunc pretium in. Nullam leo tortor, tincidunt in sodales dapibus, faucibus vel lacus. Nunc ornare lacus eu dui consequat, fermentum tincidunt felis blandit. Vivamus a turpis eros. Donec faucibus mi in magna cursus maximus. Duis ac elit posuere, bibendum nunc vel, consectetur neque. Aliquam non bibendum quam. Nulla facilisi. Vivamus eu iaculis felis. Donec elit augue, pretium eget pretium ullamcorper, vestibulum eu lorem. Praesent gravida condimentum tortor, in dignissim mauris elementum quis. Morbi a venenatis odio. Vivamus quis magna eget elit pellentesque elementum. Nulla facilisi.'}
schema={schema}
/>
</>
)
}
export default Home;

View file

@ -198,6 +198,8 @@ export const Default: Story = {
args: {
title: "St. Christophorus",
image: chris,
events: [],
worship: [],
description: "Die St. Christophorus Kirche in Berlin-Neukölln ist ein bedeutendes Beispiel für modernen Kirchenbau in der Hauptstadt. Erbaut in den 1960er Jahren, spiegelt das Gebäude die Architektur und künstlerische Gestaltung dieser Zeit wider und zeichnet sich durch schlichte, klare Linien und einen funktionalen Stil aus. Die Kirche ist nach dem heiligen Christophorus benannt, dem Schutzpatron der Reisenden, und bietet den Gemeindemitgliedern und Besuchern einen Ort der Ruhe und Besinnung im lebhaften Stadtteil Neukölln. Neben Gottesdiensten finden hier regelmäßig kulturelle Veranstaltungen und soziale Projekte statt, die die Kirche zu einem wichtigen Treffpunkt im Kiez machen.",
history: `Am 27.Juni 1929 erschien folgende Niederschrift in der Märkischen Volkszeitung, die eine berechtigte Freude über die Nachricht von dem Bau der neuen Kirche am Reuterplatz auslöste:
@ -235,5 +237,5 @@ pfarramt@christophorus-berlin.de
Bürozeiten:
Freitags 09:00 - 12:00 Uhr `
}
},
};

View file

@ -58,9 +58,9 @@ export interface Config {
user: User & {
collection: 'users';
};
jobs?: {
jobs: {
tasks: unknown;
workflows?: unknown;
workflows: unknown;
};
}
export interface UserAuthOperations {

2801
yarn.lock

File diff suppressed because it is too large Load diff