feature: some work done
|
|
@ -1 +0,0 @@
|
|||
export const importMap = {}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
import './custom.scss'
|
||||
import { importMap } from './admin/importMap'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => (
|
||||
<RootLayout importMap={importMap} config={configPromise}>
|
||||
{children}
|
||||
</RootLayout>
|
||||
)
|
||||
|
||||
export default Layout
|
||||
|
|
@ -2,6 +2,7 @@ $base-color: #426156;
|
|||
$shade1: #728F8D;
|
||||
$shade2: #CBD6D5;
|
||||
$shade3: #E3E9E8;
|
||||
$contrast-color: #9785A9;
|
||||
$contrast-shade1: #E0DAE5;
|
||||
$text-color: #000000;
|
||||
$contrast-color: #ffffff;
|
||||
$border-radius: 13px;
|
||||
|
|
@ -2,10 +2,6 @@ import { withPayload } from '@payloadcms/next/withPayload'
|
|||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: "export",
|
||||
images: {
|
||||
unoptimized: true
|
||||
},
|
||||
// Your Next.js config here
|
||||
eslint: {
|
||||
// Warning: This allows production builds to successfully complete even if
|
||||
|
|
|
|||
17
package.json
|
|
@ -17,18 +17,19 @@
|
|||
"chromatic": "npx chromatic --project-token=chpt_70d6a2e05af185a"
|
||||
},
|
||||
"dependencies": {
|
||||
"@payloadcms/db-mongodb": "3.0.0-beta.99",
|
||||
"@payloadcms/next": "3.0.0-beta.99",
|
||||
"@payloadcms/plugin-cloud": "3.0.0-beta.99",
|
||||
"@payloadcms/richtext-lexical": "3.0.0-beta.99",
|
||||
"@payloadcms/db-mongodb": "beta",
|
||||
"@payloadcms/next": "beta",
|
||||
"@payloadcms/plugin-cloud": "beta",
|
||||
"@payloadcms/richtext-lexical": "beta",
|
||||
"classnames": "^2.5.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.8.1",
|
||||
"mapbox-gl": "^3.5.2",
|
||||
"next": "^15.0.2",
|
||||
"payload": "3.0.0-beta.99",
|
||||
"react": "19.0.0-rc-f65ac7bd-20240826",
|
||||
"react-dom": "19.0.0-rc-f65ac7bd-20240826",
|
||||
"next": "15.0.0",
|
||||
"payload": "beta",
|
||||
"qs-esm": "^7.0.2",
|
||||
"react": "19.0.0-rc-65a56d0e-20241020",
|
||||
"react-dom": "19.0.0-rc-65a56d0e-20241020",
|
||||
"sharp": "0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
import { importMap } from '../importMap'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
import { importMap } from '../importMap'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
47
src/app/(payload)/admin/importMap.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
|
||||
export const importMap = {
|
||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864
|
||||
}
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
|
||||
import '@payloadcms/next/css'
|
||||
import {
|
||||
REST_DELETE,
|
||||
REST_GET,
|
||||
REST_OPTIONS,
|
||||
REST_PATCH,
|
||||
REST_POST,
|
||||
REST_PUT,
|
||||
} from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = REST_GET(config)
|
||||
export const POST = REST_POST(config)
|
||||
export const DELETE = REST_DELETE(config)
|
||||
export const PATCH = REST_PATCH(config)
|
||||
export const PUT = REST_PUT(config)
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
8
src/app/(payload)/api/graphql/route.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
31
src/app/(payload)/layout.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import type { ServerFunctionClient } from 'payload'
|
||||
import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
|
||||
import React from 'react'
|
||||
|
||||
import { importMap } from './admin/importMap.js'
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const serverFunction: ServerFunctionClient = async function (args) {
|
||||
'use server'
|
||||
return handleServerFunctions({
|
||||
...args,
|
||||
config,
|
||||
importMap,
|
||||
})
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => (
|
||||
<RootLayout config={config} importMap={importMap} serverFunction={serverFunction}>
|
||||
{children}
|
||||
</RootLayout>
|
||||
)
|
||||
|
||||
export default Layout
|
||||
45
src/app/blog/[id]/page.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { ContentWithSlider } from '@/compositions/ContentWithSlider/ContentWithSlider'
|
||||
import { TextDiv } from '@/components/Text/TextDiv'
|
||||
import { Blog } from '@/payload-types'
|
||||
import { notFound } from 'next/navigation'
|
||||
|
||||
async function fetchBlog(id: string) {
|
||||
const res = await fetch(`http://localhost:3000/api/blog/${id}`)
|
||||
if (!res.ok) return undefined
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export default async function BlogPage({ params }: { params: Promise<{id: string}>}){
|
||||
|
||||
const id = (await params).id;
|
||||
const data = await fetchBlog(id) as Blog;
|
||||
|
||||
if(!data) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<Container>
|
||||
<Title title={data.title}></Title>
|
||||
</Container>
|
||||
<div>
|
||||
{data.content && data.content.map(item => {
|
||||
if (item.blockType === "ContentWithSlider") {
|
||||
return (
|
||||
<ContentWithSlider key={item.id} slider={item.sliderContent}>
|
||||
<Container position={"right"}>
|
||||
<TextDiv text={item.content} />
|
||||
</Container>
|
||||
</ContentWithSlider>
|
||||
);
|
||||
}
|
||||
|
||||
})}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
BIN
src/app/bread.jpg
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src/app/candle.png
Normal file
|
After Width: | Height: | Size: 826 KiB |
|
|
@ -7,6 +7,6 @@ export const faustina = Faustina({
|
|||
|
||||
export const defaultFont = Cairo({
|
||||
subsets: ['latin'],
|
||||
weight: ['400'],
|
||||
weight: ['400', '300'],
|
||||
display: 'swap',
|
||||
})
|
||||
|
|
|
|||
53
src/app/gemeinde/[slug]/page.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { PaginatedDocs } from 'payload'
|
||||
import { Parish as ParishType } from '@/payload-types'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { Parish } from "@/pageComponents/Parish/Parish"
|
||||
import { stringify } from 'qs-esm'
|
||||
import { fetchEvents } from '@/fetch/events'
|
||||
import { fetchWorship } from '@/fetch/worship'
|
||||
|
||||
async function fetchParish(slug: string) {
|
||||
const query = {
|
||||
slug: {
|
||||
equals: slug
|
||||
}
|
||||
}
|
||||
|
||||
const stringifiedQuery = stringify(
|
||||
{
|
||||
where: query,
|
||||
},
|
||||
{ addQueryPrefix: true },
|
||||
)
|
||||
|
||||
const res = await fetch(`http://localhost:3000/api/parish${stringifiedQuery}`)
|
||||
if (!res.ok) return undefined
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export default async function ParishPage ({ params }: { params: Promise<{slug: string}>}) {
|
||||
|
||||
const slug = (await params).slug;
|
||||
const parish = await fetchParish(slug) as PaginatedDocs<ParishType>
|
||||
|
||||
if(!parish.docs[0]) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const { id, name, description, history, contactPersons, contact, photo, churches } = parish.docs[0]
|
||||
const events = await fetchEvents(id)
|
||||
const worship = await fetchWorship(churches.map(c => typeof c === "string" ? c : c.id))
|
||||
return (
|
||||
<Parish
|
||||
title={name}
|
||||
slug={slug}
|
||||
image={typeof photo === "string" ? photo : photo.url || "notfound"}
|
||||
description={description}
|
||||
history={history}
|
||||
contactPersons={contactPersons || []}
|
||||
contact={contact}
|
||||
events={events?.docs || []}
|
||||
worship={worship?.docs || []}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,4 +1,11 @@
|
|||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
|
|
|||
70
src/app/gottesdienst/[id]/page.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { Worship } from '@/payload-types'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { HR } from '@/components/HorizontalRule/HorizontalRule'
|
||||
import { liturgicalDayName } from '@/hooks/liturgicalDayName'
|
||||
import { ChurchWithContact } from '@/compositions/ChurchWithContact/ChurchWithContact'
|
||||
import { transformCategory } from '@/utils/dto/worship'
|
||||
import { readableDateTime } from '@/utils/readableDate'
|
||||
|
||||
export default async function WorshipPage({ params }: { params: Promise<{id: string}>}) {
|
||||
|
||||
const id = (await params).id;
|
||||
const res = await fetch(`http://localhost:3000/api/worship/${id}`);
|
||||
if (!res.ok) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const event = await res.json() as Worship;
|
||||
const subtitle = event.title ? event.title : transformCategory(event.type);
|
||||
const title = event.liturgicalDay ? event.liturgicalDay : liturgicalDayName(event.date);
|
||||
const church = typeof event.location === "string" ? { name: "Unkown", address: "unknown"} : event.location;
|
||||
return (
|
||||
<>
|
||||
<Section>
|
||||
<Container>
|
||||
<Title title={title} subtitle={subtitle} />
|
||||
</Container>
|
||||
<HR/>
|
||||
</Section>
|
||||
|
||||
<Section backgroundColor={"off-white"}>
|
||||
<Container textAlign="center">
|
||||
<>
|
||||
<p>
|
||||
<strong>{church.name}</strong> <br/>
|
||||
{readableDateTime(event.date)}
|
||||
</p>
|
||||
|
||||
{ event.celebrant &&
|
||||
<p>
|
||||
<strong>Zelebrant</strong><br/>
|
||||
{event.celebrant}
|
||||
</p>
|
||||
}
|
||||
|
||||
{event.description &&
|
||||
<p>
|
||||
<strong>Hinweis</strong><br />
|
||||
{event.description}
|
||||
</p>
|
||||
}
|
||||
</>
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
|
||||
<Section>
|
||||
<Container>
|
||||
<ChurchWithContact
|
||||
church={church.name}
|
||||
contact={church.address}
|
||||
/>
|
||||
</Container>
|
||||
</Section>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import type { Metadata } from 'next'
|
||||
import { defaultFont } from './fonts'
|
||||
import './globals.css'
|
||||
import { Menu } from '@/components/Menu/Menu'
|
||||
import { Footer } from '@/compositions/Footer/Footer'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Katholische Pfarrei Heilige drei Könige Berlin',
|
||||
|
|
@ -13,7 +15,13 @@ export default function RootLayout({
|
|||
}>) {
|
||||
return (
|
||||
<html lang="en" className={defaultFont.className}>
|
||||
<body>{children}</body>
|
||||
<body>
|
||||
<Menu />
|
||||
<main>
|
||||
{children}
|
||||
</main>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
BIN
src/app/mons.jpg
Normal file
|
After Width: | Height: | Size: 110 KiB |
|
|
@ -1,15 +1,49 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
|
||||
export default function Custom404() {
|
||||
return (
|
||||
<>
|
||||
<h1>404 - Seite nicht gefunden</h1>
|
||||
<Section>
|
||||
<Container>
|
||||
<Title title={"Seite nicht gefunden"} />
|
||||
|
||||
<p>
|
||||
Glorreicher heiliger Antonius, du hast die göttliche Macht ausgeübt,
|
||||
verlorene Dinge wiederzufinden. Hilf uns, die Gnade Gottes
|
||||
wiederzuerlangen und mach mich stark im Dienst an Gott und an den
|
||||
Tugenden. Lass' mich das Verlorene wiederfinden und zeige mir so
|
||||
deine Güte.
|
||||
</p>
|
||||
<p>
|
||||
Error <strong>404</strong>: Die von Ihnen angeforderte Seite existiert leider nicht.
|
||||
</p>
|
||||
|
||||
<Title title={"Mögliche Gründe"} size={"sm"} fontStyle={"sans-serif"}/>
|
||||
|
||||
<ul>
|
||||
<li>Die URL wurde falsch eingegeben.</li>
|
||||
<li>Die Seite wurde verschoben oder entfernt.</li>
|
||||
<li>Der Link ist veraltet.</li>
|
||||
</ul>
|
||||
|
||||
</Container>
|
||||
</Section>
|
||||
<Section backgroundColor={"off-white"}>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<p>
|
||||
Glorreicher heiliger Antonius, du hast die göttliche Macht ausgeübt,
|
||||
verlorene Dinge wiederzufinden. Hilf uns, die Gnade Gottes
|
||||
wiederzuerlangen und mach mich stark im Dienst an Gott und an den
|
||||
Tugenden. Lass' mich das Verlorene wiederfinden und zeige mir so
|
||||
deine Güte.
|
||||
</p>
|
||||
</Col>
|
||||
<Col>
|
||||
<></>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</Container>
|
||||
</Section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
195
src/app/page.tsx
|
|
@ -1,85 +1,71 @@
|
|||
import { Menu } from '@/components/Menu/Menu'
|
||||
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 { ImageCardSlider } from '@/compositions/ImageCardSlider/ImageCardSlider'
|
||||
import { ImageWithText } from '@/compositions/ImageWithText/ImageWithText'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { ContactSection } from '@/compositions/ContactSection/ContactSection'
|
||||
import { Footer } from '@/compositions/Footer/Footer'
|
||||
import { EventRow } from '@/components/EventRow/EventRow'
|
||||
import monst from "./mons.jpg"
|
||||
import bread from "./bread.jpg"
|
||||
import candle from "./candle.png"
|
||||
import { SideSlider } from '@/components/SideSlider/SideSlider'
|
||||
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 { Row } from '@/components/Flex/Row'
|
||||
import { transformEvents } from '@/utils/dto/events'
|
||||
import { fetchBlog } from '@/fetch/blog'
|
||||
import { ImageCardSlider } from '@/compositions/ImageCardSlider/ImageCardSlider'
|
||||
import { blogToSlides } from '@/utils/dto/blog'
|
||||
|
||||
// const extractWorshipHours = (worships: Worship[]) => {
|
||||
// let worshipByDate = new Map<string, Worship[]>()
|
||||
//
|
||||
// for (let worship of worships) {
|
||||
// const date = worship.date.substring(0, 10)
|
||||
//
|
||||
// if (worshipByDate.has(date)) {
|
||||
// worshipByDate.get(date)?.push(worship)
|
||||
// } else {
|
||||
// worshipByDate.set(date, [worship])
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return worshipByDate
|
||||
// }
|
||||
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 dynamic = 'force-dynamic'
|
||||
|
||||
export default async function Home() {
|
||||
// const today = new Date()
|
||||
// const nextWeek = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000)
|
||||
// const payload = await getPayloadHMR({ config: configPromise })
|
||||
// const worship = await payload.find({
|
||||
// collection: 'worship',
|
||||
// where: {
|
||||
// and: [
|
||||
// {
|
||||
// date: {
|
||||
// greater_than_equal: today.toISOString().substring(0, 10),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// date: {
|
||||
// less_than: nextWeek.toISOString().substring(0, 10),
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// limit: 30,
|
||||
// sort: 'date',
|
||||
// })
|
||||
//
|
||||
// const nextMass = await payload.find({
|
||||
// collection: 'worship',
|
||||
// where: {
|
||||
// and: [
|
||||
// {
|
||||
// date: {
|
||||
// greater_than_equal: today.toISOString(),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// cancelled: {
|
||||
// equals: false,
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// limit: 1,
|
||||
// sort: 'date',
|
||||
// })
|
||||
//
|
||||
// const worshipByDate = [...extractWorshipHours(worship.docs).entries()]
|
||||
|
||||
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();
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Menu/>
|
||||
<Banner/>
|
||||
|
||||
<Container>
|
||||
|
|
@ -88,32 +74,23 @@ export default async function Home() {
|
|||
"Wie die drei Weisen aus dem Morgenland wollen wir uns immer wieder neu auf den Weg machen."} />
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<Title title={"Unsere Gottesdiensten"} align={"center"}/>
|
||||
|
||||
<Row>
|
||||
{worshipPerLocation.map(value => <MassTable key={value[0]} location={value[0]} masses={value[1]} />)}
|
||||
</Row>
|
||||
</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"
|
||||
}
|
||||
]} />
|
||||
<ImageCardSlider slides={blogToSlides(blog?.docs || [])} />
|
||||
</Section>
|
||||
</Container>
|
||||
|
||||
<ImageWithText />
|
||||
{<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"} />
|
||||
|
|
@ -121,50 +98,12 @@ export default async function Home() {
|
|||
<Container position={"right"}>
|
||||
<Section>
|
||||
<Title title={"Veranstaltungen"} />
|
||||
<EventRow
|
||||
date={"2024-10-23T16:00:00"}
|
||||
title={"Gemeinsam beten"}
|
||||
href={"https://link"}
|
||||
location={"St. Christophorus"}
|
||||
/>
|
||||
<EventRow
|
||||
date={"2024-10-28T19:45:00"}
|
||||
title={"Rosenkranz"}
|
||||
href={"https://link"}
|
||||
location={"St. Clara"}
|
||||
/>
|
||||
<EventRow
|
||||
date={"2024-11-02T19:00:00"}
|
||||
title={"Allerseelen"}
|
||||
href={"https://link"}
|
||||
location={"St. Michael"}
|
||||
/>
|
||||
<EventRow
|
||||
date={"2024-11-11T18:00:00"}
|
||||
title={"St. Martin"}
|
||||
href={"https://link"}
|
||||
location={"Sportplatz St. Christophorus"}
|
||||
/>
|
||||
<EventRow
|
||||
date={"2024-11-11T18:00:00"}
|
||||
title={"St. Martin"}
|
||||
href={"https://link"}
|
||||
location={"Sportplatz St. Christophorus"}
|
||||
/>
|
||||
<EventRow
|
||||
date={"2024-11-11T18:00:00"}
|
||||
title={"St. Martin"}
|
||||
href={"https://link"}
|
||||
location={"Sportplatz St. Christophorus"}
|
||||
/>
|
||||
<Events events={transformEvents(events?.docs || [])} n={6}/>
|
||||
</Section>
|
||||
</Container>
|
||||
</ContentWithSlider>
|
||||
|
||||
<ContactSection />
|
||||
|
||||
<Footer />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
47
src/app/veranstaltungen/[id]/page.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { Event } from '@/payload-types'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { HR } from '@/components/HorizontalRule/HorizontalRule'
|
||||
import { readableDateTime } from '@/utils/readableDate'
|
||||
import { TextDiv } from '@/components/Text/TextDiv'
|
||||
|
||||
export default async function EventPage({ params }: { params: Promise<{id: string}>}) {
|
||||
|
||||
const id = (await params).id;
|
||||
const res = await fetch(`http://localhost:3000/api/event/${id}?depth=0`);
|
||||
|
||||
if (!res.ok) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const event = await res.json() as Event;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section>
|
||||
<Container>
|
||||
<Title
|
||||
title={event.title}
|
||||
subtitle={readableDateTime(event.date)}
|
||||
size={"xl"}/>
|
||||
</Container>
|
||||
|
||||
<HR />
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<Container textAlign={"center"}>
|
||||
<TextDiv text={event.shortDescription} />
|
||||
<p>
|
||||
<strong>Location</strong> <br/>
|
||||
{event.location}
|
||||
</p>
|
||||
</Container>
|
||||
</Section>
|
||||
</>
|
||||
|
||||
|
||||
)
|
||||
}
|
||||
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 12 MiB After Width: | Height: | Size: 12 MiB |
|
|
@ -1,6 +1,37 @@
|
|||
import { CollectionConfig } from 'payload'
|
||||
import { Block, CollectionConfig } from 'payload'
|
||||
import { isAdminOrEmployee } from '@/collections/access/admin'
|
||||
|
||||
const QuoteBlock: Block = {
|
||||
slug: 'Quote',
|
||||
labels: {
|
||||
singular: "Zitat",
|
||||
plural: "Zitaten"
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'quoteText',
|
||||
type: 'text',
|
||||
required: true
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const ContentWithSlider: Block = {
|
||||
slug: 'ContentWithSlider',
|
||||
fields: [
|
||||
{
|
||||
name: 'sliderContent',
|
||||
type: 'textarea',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'textarea',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const Blog: CollectionConfig = {
|
||||
slug: 'blog',
|
||||
labels: {
|
||||
|
|
@ -35,21 +66,14 @@ export const Blog: CollectionConfig = {
|
|||
}
|
||||
},
|
||||
{
|
||||
name: 'isHighlight',
|
||||
type: 'checkbox',
|
||||
required: true,
|
||||
label: {
|
||||
de: "Highlight"
|
||||
},
|
||||
defaultValue: false
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
type: 'richText',
|
||||
required: true,
|
||||
label: {
|
||||
de: "Post"
|
||||
}
|
||||
name: 'content',
|
||||
type: 'blocks',
|
||||
minRows: 1,
|
||||
maxRows: 20,
|
||||
blocks: [
|
||||
QuoteBlock,
|
||||
ContentWithSlider
|
||||
]
|
||||
}
|
||||
],
|
||||
admin: {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export const Events: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: 'datum',
|
||||
name: 'date',
|
||||
type: 'date',
|
||||
required: true,
|
||||
label: {
|
||||
|
|
@ -41,6 +41,14 @@ export const Events: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'location',
|
||||
type: 'text',
|
||||
required: true,
|
||||
label: {
|
||||
de: 'Location'
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'parish',
|
||||
type: 'relationship',
|
||||
|
|
@ -70,7 +78,7 @@ export const Events: CollectionConfig = {
|
|||
label: {
|
||||
de: 'Gruppe',
|
||||
},
|
||||
validate: (value, options) => {
|
||||
validate: (value: any, options: { req: { user: any } }) => {
|
||||
let user = options.req.user
|
||||
|
||||
if (!user) {
|
||||
|
|
|
|||
|
|
@ -51,23 +51,29 @@ export const Parish: CollectionConfig = {
|
|||
hasMany: true,
|
||||
},
|
||||
{
|
||||
name: 'contact',
|
||||
name: 'contactPersons',
|
||||
label: {
|
||||
de: 'Kontaktinformation',
|
||||
de: "Ansprechpartner"
|
||||
},
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
admin: {
|
||||
rows: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
label: {
|
||||
de: 'Titel',
|
||||
},
|
||||
type: 'text',
|
||||
required: true,
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
label: {
|
||||
de: 'Titel'
|
||||
},
|
||||
type: 'text',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: {
|
||||
de: 'Umschreibung'
|
||||
},
|
||||
type: 'textarea',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
|
|
@ -80,10 +86,33 @@ export const Parish: CollectionConfig = {
|
|||
rows: 15,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'history',
|
||||
label: {
|
||||
de: 'Geschichte',
|
||||
},
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
admin: {
|
||||
rows: 15,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'contact',
|
||||
label: {
|
||||
de: 'Kontaktinformation',
|
||||
},
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
admin: {
|
||||
rows: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'photo',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: true
|
||||
},
|
||||
],
|
||||
admin: {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,14 @@ export const Worship: CollectionConfig = {
|
|||
],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: false,
|
||||
label: {
|
||||
de: 'Titel'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'cancelled',
|
||||
type: 'checkbox',
|
||||
|
|
@ -66,13 +74,21 @@ export const Worship: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
name: 'liturgicalDay',
|
||||
type: 'text',
|
||||
required: false,
|
||||
label: {
|
||||
de: 'Liturgischer Tag',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'celebrant',
|
||||
type: 'text',
|
||||
required: false,
|
||||
label: {
|
||||
de: 'Zelebrant'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
|
|
@ -81,6 +97,10 @@ export const Worship: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
],
|
||||
admin: {
|
||||
defaultColumns: ["date", 'location', 'type', 'celebrant'],
|
||||
listSearchableFields: ['date', 'location']
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
create: isAdminOrEmployee(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
.button {
|
||||
background: $shade1;
|
||||
color: $contrast-color;
|
||||
color: $shade3;
|
||||
border-radius: $border-radius;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
|
|
|
|||
24
src/components/ChurchCard/ChurchCard.stories.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { ChurchCard } from './ChurchCard'
|
||||
|
||||
const meta: Meta<typeof ChurchCard> = {
|
||||
component: ChurchCard,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof ChurchCard>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
church: "anna",
|
||||
backgroundColor: "#E0DAE5"
|
||||
},
|
||||
}
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
church: "anna",
|
||||
backgroundColor: "#E0DAE5",
|
||||
width: 100
|
||||
},
|
||||
}
|
||||
|
|
@ -1,3 +1,14 @@
|
|||
export const ChurchCard = () => {
|
||||
import styles from './styles.module.scss'
|
||||
import { Church, ChurchIcon } from '@/components/ChurchIcon/ChurchIcon'
|
||||
|
||||
type ChurchCardProps = {
|
||||
church: Church,
|
||||
width?: number,
|
||||
backgroundColor: string,
|
||||
}
|
||||
|
||||
export const ChurchCard = ({church, backgroundColor, width = 286 }: ChurchCardProps) => {
|
||||
return <div className={styles.card} style={{backgroundColor, width, height: width}}>
|
||||
<ChurchIcon church={church} style={"outline"} stroke={0.5} color={"#000000"} />
|
||||
</div>
|
||||
}
|
||||
12
src/components/ChurchCard/styles.module.scss
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
@import "template.scss";
|
||||
|
||||
.card {
|
||||
border-radius: $border-radius;
|
||||
border: 1px solid $shade2;
|
||||
box-shadow: 3px 7px 26px 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.card svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -3,6 +3,11 @@ import { ChurchIcon } from './ChurchIcon'
|
|||
|
||||
const meta: Meta<typeof ChurchIcon> = {
|
||||
component: ChurchIcon,
|
||||
decorators: [
|
||||
(Story) => <div style={{width: "50px", height: "50px"}} >
|
||||
<Story/>
|
||||
</div>
|
||||
]
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof ChurchIcon>;
|
||||
|
|
@ -10,30 +15,45 @@ export default meta
|
|||
|
||||
export const StClara: Story = {
|
||||
args: {
|
||||
church: "clara"
|
||||
church: "clara",
|
||||
style: "outline",
|
||||
stroke: 3,
|
||||
color: "#426156",
|
||||
},
|
||||
}
|
||||
|
||||
export const StChristophorus: Story = {
|
||||
args: {
|
||||
church: "christophorus"
|
||||
church: "christophorus",
|
||||
style: "outline",
|
||||
stroke: 3,
|
||||
color: "#426156",
|
||||
},
|
||||
}
|
||||
|
||||
export const StRichard: Story = {
|
||||
args: {
|
||||
church: "richard"
|
||||
church: "richard",
|
||||
style: "outline",
|
||||
stroke: 3,
|
||||
color: "#426156",
|
||||
},
|
||||
}
|
||||
|
||||
export const StEduard: Story = {
|
||||
args: {
|
||||
church: "eduard"
|
||||
church: "eduard",
|
||||
style: "outline",
|
||||
stroke: 3,
|
||||
color: "#426156",
|
||||
},
|
||||
}
|
||||
|
||||
export const StAnna: Story = {
|
||||
args: {
|
||||
church: "anna"
|
||||
church: "anna",
|
||||
style: "outline",
|
||||
stroke: 3,
|
||||
color: "#426156",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,32 +1,56 @@
|
|||
import christophorus from "./christophorus_full.svg"
|
||||
import clara from "./clara_full.svg"
|
||||
import anna from "./anna_full.svg"
|
||||
import richard from "./richard_full.svg"
|
||||
import eduard from "./eduard_full.svg"
|
||||
import Image from 'next/image'
|
||||
|
||||
export type Church = "clara" | "christophorus" | "richard" | "eduard" | "anna"
|
||||
|
||||
type ChurchIconProps = {
|
||||
church: "clara" | "christophorus" | "richard" | "eduard" | "anna"
|
||||
church: Church
|
||||
style: "outline" | "filled"
|
||||
stroke: number
|
||||
color: string
|
||||
}
|
||||
|
||||
export const ChurchIcon = ({church}: ChurchIconProps) => {
|
||||
export const ChurchIcon = ({church, style, stroke, color}: ChurchIconProps) => {
|
||||
if (church === "clara") {
|
||||
return <Image src={clara} alt={""} />
|
||||
return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g fill={style === 'outline' ? '#ffffff' : color} stroke={color} strokeWidth={stroke}>
|
||||
<polygon
|
||||
points="152.25 185.47 103.11 145.09 103.11 134.29 105.39 134.29 105.39 133.29 103.11 133.29 103.11 128.18 102.11 128.18 102.11 133.29 99.68 133.29 99.68 134.29 102.11 134.29 102.11 145.09 86.5 158.05 86.5 128.09 60.44 42.14 60.44 32.72 62.72 32.72 62.72 31.72 60.44 31.72 60.44 26.61 59.44 26.61 59.44 31.72 57.01 31.72 57.01 32.72 59.44 32.72 59.44 42.12 38.88 111.48 38.86 248.62 86 248.22 169.49 248.22 169.49 185.47 152.25 185.47" />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
if (church === "anna") {
|
||||
return <Image src={anna} alt={""} />
|
||||
if (church === 'anna') {
|
||||
return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g fill={style === 'outline' ? '#ffffff' : color} stroke={color} strokeWidth={stroke}>
|
||||
<polygon
|
||||
points="143.86 114.51 143.86 73.97 112.05 56.84 112.05 46.53 114.33 46.53 114.33 45.53 112.05 45.53 112.05 40.42 111.05 40.42 111.05 45.53 108.62 45.53 108.62 46.53 111.05 46.53 111.05 56.83 79.7 74.46 79.7 114.76 33.67 126.02 33.43 217.49 33.42 217.99 190.52 217.99 190.52 125.78 143.86 114.51" />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
if (church === "richard") {
|
||||
return <Image src={richard} alt={""} />
|
||||
if (church === 'richard') {
|
||||
return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g fill={style === "outline" ? "#ffffff" : color} stroke={color} strokeWidth={stroke}>
|
||||
<path
|
||||
d="M87,80.23l-.23-.06L32.13,120.86v74.19H204.49V109.29Zm18,24.13h-2.28v11h-1v-11H99.32v-1h2.43V98.25h1v5.11H105Z" />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
if (church === "eduard") {
|
||||
return <Image src={eduard} alt={""} />
|
||||
if (church === 'eduard') {
|
||||
return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g fill={style === "outline" ? "#ffffff" : color} stroke={color} strokeWidth={stroke}>
|
||||
<polygon
|
||||
points="152.15 168.04 132.61 179.16 132.61 134.31 109.83 37.44 109.83 26.46 112.11 26.46 112.11 25.46 109.83 25.46 109.83 20.35 108.83 20.35 108.83 25.46 106.4 25.46 106.4 26.46 108.83 26.46 108.83 37.44 85.57 133.71 85.56 168.01 74.7 168.01 58.33 191.25 58.24 191.38 58.24 254.87 184.49 254.87 184.49 196.72 152.15 168.04" />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
return (
|
||||
<Image src={christophorus} alt={"chris"} />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g fill={style === "outline" ? "#ffffff" : color} stroke={color} strokeWidth={stroke}>
|
||||
<polygon
|
||||
points="138.03 54.42 138.03 44.29 140.3 44.29 140.3 43.29 138.03 43.29 138.03 38.18 137.03 38.18 137.03 43.29 134.6 43.29 134.6 44.29 137.03 44.29 137.03 54.44 94.55 71.65 94.55 186.65 71.4 203.88 71.4 209.82 42.03 209.9 42.07 232.89 174.94 232.89 174.94 72.21 138.03 54.42" />
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -1 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 239.12 255.74"><defs><style>.cls-1{fill:#426156;}</style></defs><g id="St._Anna" data-name="St. Anna"><path class="cls-1" d="M152.23,122.54V82L120.42,64.87V54.56h2.28v-1h-2.28V48.45h-1v5.11H117v1h2.43v10.3L88.07,82.49v40.3L42,134.05l-.24,91.47v.5h157.1V133.81ZM88.07,225H42.8L43,134.84l45-11Zm63.16,0H89.07V83.08l30.84-17.35,31.32,16.86Zm46.66,0H152.23V123.57l45.66,11Z"/><polygon class="cls-1" points="197.89 134.59 197.89 225.02 152.23 225.02 152.23 123.57 197.89 134.59"/><polygon class="cls-1" points="151.23 82.59 151.23 225.02 89.07 225.02 89.07 83.08 119.91 65.73 151.23 82.59"/><polygon class="cls-1" points="88.07 123.82 88.07 225.02 42.8 225.02 43.04 134.84 88.07 123.82"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g id="Full_Violet" data-name="Full Violet">
|
||||
<polygon class="cls-1"
|
||||
points="143.86 114.51 143.86 73.97 112.05 56.84 112.05 46.53 114.33 46.53 114.33 45.53 112.05 45.53 112.05 40.42 111.05 40.42 111.05 45.53 108.62 45.53 108.62 46.53 111.05 46.53 111.05 56.83 79.7 74.46 79.7 114.76 33.67 126.02 33.43 217.49 33.42 217.99 190.52 217.99 190.52 125.78 143.86 114.51"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 746 B After Width: | Height: | Size: 479 B |
|
|
@ -1,30 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 175.75 265.12"
|
||||
version="1.1"
|
||||
id="svg34"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs27">
|
||||
<style
|
||||
id="style25">.cls-1{fill:#426156;}</style>
|
||||
</defs>
|
||||
<g
|
||||
id="St._Christophorus"
|
||||
data-name="St. Christophorus">
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M 114.44,72.08 V 62 h 2.27 v -1 h -2.27 v -5.16 h -1 V 61 H 111 v 1 h 2.43 V 72.1 L 71,89.31 v 115 l -23.19,17.23 v 5.94 l -29.37,0.08 v 23 H 151.35 V 89.87 Z M 113.93,73 c -75.953333,-48.666667 -37.976667,-24.333333 0,0 z"
|
||||
id="path29" />
|
||||
</g>
|
||||
<g
|
||||
id="fill">
|
||||
<polygon
|
||||
class="cls-1"
|
||||
points="113.89,72.99 114.02,72.99 150.35,90.49 150.35,249.55 19.48,249.55 19.44,228.56 48.81,228.48 48.81,222.04 71.96,204.81 71.96,89.98 "
|
||||
id="polygon31"
|
||||
style="fill:#426156"
|
||||
transform="translate(0.04,0.01)" />
|
||||
</g>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g id="White_Mask" data-name="White Mask">
|
||||
<polygon class="cls-3"
|
||||
points="138.03 54.42 138.03 44.29 140.3 44.29 140.3 43.29 138.03 43.29 138.03 38.18 137.03 38.18 137.03 43.29 134.6 43.29 134.6 44.29 137.03 44.29 137.03 54.44 94.55 71.65 94.55 186.65 71.4 203.88 71.4 209.82 42.03 209.9 42.07 232.89 174.94 232.89 174.94 72.21 138.03 54.42"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 972 B After Width: | Height: | Size: 456 B |
|
|
@ -1 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 175.75 265.12"><defs><style>.cls-1{fill:#426156;}</style></defs><g id="St._Eduard" data-name="St. Eduard"><path class="cls-1" d="M136.16,177.51,87,137.13v-10.8H89.3v-1H87v-5.11H86v5.11H83.59v1H86v10.8l-15.61,13v-30L44.35,34.18V24.76h2.28v-1H44.35V18.65h-1v5.11H40.92v1h2.43v9.4L22.79,103.52l0,137.14,47.14-.4H153.4V177.51ZM69.41,239.27l-45.64.38V103.74L43.85,36,69.41,120.2Zm83,0h-82V151.39L86.52,138l49.28,40.49h16.6Z"/><polygon class="cls-1" points="152.4 178.51 152.4 239.26 70.41 239.26 70.41 151.39 86.52 138.02 135.8 178.51 152.4 178.51"/><polygon class="cls-1" points="69.41 120.2 69.41 239.27 23.77 239.65 23.77 103.74 43.85 35.98 69.41 120.2"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g>
|
||||
<polygon
|
||||
points="152.25 185.47 103.11 145.09 103.11 134.29 105.39 134.29 105.39 133.29 103.11 133.29 103.11 128.18 102.11 128.18 102.11 133.29 99.68 133.29 99.68 134.29 102.11 134.29 102.11 145.09 86.5 158.05 86.5 128.09 60.44 42.14 60.44 32.72 62.72 32.72 62.72 31.72 60.44 31.72 60.44 26.61 59.44 26.61 59.44 31.72 57.01 31.72 57.01 32.72 59.44 32.72 59.44 42.12 38.88 111.48 38.86 248.62 86 248.22 169.49 248.22 169.49 185.47 152.25 185.47"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 716 B After Width: | Height: | Size: 563 B |
|
|
@ -1,14 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 175.75 265.12">
|
||||
<defs>
|
||||
<style>.cls-1{fill:#426156;}</style>
|
||||
</defs>
|
||||
<g id="St._Eduard" data-name="St. Eduard">
|
||||
<path class="cls-1"
|
||||
d="M117.83,161.61,98.29,172.73V127.88L75.51,31V20h2.28V19H75.51V13.92h-1V19H72.08v1h2.43V31L51.25,127.28v34.3H40.38L24,184.82l-.09.13v63.49H150.17V190.29ZM51.24,247.44H24.92V185.26l16-22.68H51.24Zm46.05,0H52.24v-120L75,33.22l22.29,94.72Zm51.88,0H98.29V173.88l19.41-11,31.47,27.91Z"/>
|
||||
<polygon class="cls-1"
|
||||
points="149.17 190.74 149.17 247.44 98.29 247.44 98.29 173.88 117.7 162.83 149.17 190.74"/>
|
||||
<polygon class="cls-1" points="97.29 127.94 97.29 247.44 52.24 247.44 52.24 127.45 75 33.22 97.29 127.94"/>
|
||||
<polygon class="cls-1" points="51.24 162.58 51.24 247.44 24.92 247.44 24.92 185.26 40.9 162.58 51.24 162.58"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g>
|
||||
<polygon
|
||||
points="152.15 168.04 132.61 179.16 132.61 134.31 109.83 37.44 109.83 26.46 112.11 26.46 112.11 25.46 109.83 25.46 109.83 20.35 108.83 20.35 108.83 25.46 106.4 25.46 106.4 26.46 108.83 26.46 108.83 37.44 85.57 133.71 85.56 168.01 74.7 168.01 58.33 191.25 58.24 191.38 58.24 254.87 184.49 254.87 184.49 196.72 152.15 168.04"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 452 B |
|
|
@ -1 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 221.52 164.2"><defs><style>.cls-1{fill:#426156;}.cls-2{fill:#728f8d;}.cls-3{fill:#fff;}</style></defs><g id="St._Christophorus" data-name="St. Christophorus"><path class="cls-1" d="M74.29,20.71l-.23-.06L19.41,61.34v74.19H191.77V49.77Zm-.62,113.82H20.41V61.84L73.67,22.19Zm117.1,0H74.67V21.83l116.1,28.73Z"/><path class="cls-2" d="M74.67,21.83v112.7h116.1v-84Zm17.64,23.1H90V56H89v-11H86.6v-1H89V38.82h1v5.11h2.28Z"/><polygon class="cls-1" points="73.67 22.19 73.67 134.53 20.41 134.53 20.41 61.84 73.67 22.19"/><polygon class="cls-3" points="92.31 43.93 92.31 44.93 90.03 44.93 90.03 55.97 89.03 55.97 89.03 44.93 86.6 44.93 86.6 43.93 89.03 43.93 89.03 38.82 90.03 38.82 90.03 43.93 92.31 43.93"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 223.94 276.25">
|
||||
<g>
|
||||
<path
|
||||
d="M87,80.23l-.23-.06L32.13,120.86v74.19H204.49V109.29Zm18,24.13h-2.28v11h-1v-11H99.32v-1h2.43V98.25h1v5.11H105Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 761 B After Width: | Height: | Size: 236 B |
17
src/components/ContactPerson/ContactPerson.stories.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { ContactPerson } from './ContactPerson'
|
||||
|
||||
const meta: Meta<typeof ContactPerson> = {
|
||||
component: ContactPerson,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof ContactPerson>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: "Kirechenvorstand",
|
||||
description: `Stellv. Vorsitzender: Michael Wolter
|
||||
Vorsitzender: Pfarrer Ulrich Kotzur`
|
||||
},
|
||||
};
|
||||
18
src/components/ContactPerson/ContactPerson.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import styles from './styles.module.scss'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
|
||||
type ContactPersonProps = {
|
||||
title: string,
|
||||
description: string
|
||||
}
|
||||
|
||||
export const ContactPerson = ({ title, description }: ContactPersonProps) => {
|
||||
return (
|
||||
<div>
|
||||
<Title title={title} size={"sm"} color={"contrast"} fontStyle={"sans-serif"} />
|
||||
<div className={styles.description}>
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
33
src/components/ContactPerson/ContactPersonList.stories.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { ContactPersonList } from './ContactPersonList'
|
||||
|
||||
const meta: Meta<typeof ContactPersonList> = {
|
||||
component: ContactPersonList,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof ContactPersonList>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
persons: [
|
||||
{
|
||||
title: "Seelsorgeteam",
|
||||
description: `Pater Karl Hermann Lenz SAC (Pfarrvikar)
|
||||
pallottis@christophorus-berlin.de
|
||||
Lissy Eichert UAC
|
||||
l.eichert@christophorus-berlin.
|
||||
`
|
||||
},
|
||||
{
|
||||
title: "Pallottinische Gemeinschaft",
|
||||
description: `Lissy Eichert UAC
|
||||
l.eichert@christophorus-berlin.de`
|
||||
},
|
||||
{
|
||||
title: "Kirechenvorstand",
|
||||
description: "Some contactinfo"
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
17
src/components/ContactPerson/ContactPersonList.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import styles from "./list.module.scss"
|
||||
import { ContactPerson } from '@/components/ContactPerson/ContactPerson'
|
||||
|
||||
type ContactPersonListProps = {
|
||||
persons: {
|
||||
title: string,
|
||||
description: string,
|
||||
}[]
|
||||
}
|
||||
|
||||
export const ContactPersonList = ({ persons }: ContactPersonListProps) => {
|
||||
return (
|
||||
<div className={styles.list}>
|
||||
{persons.map(person => <ContactPerson key={person.title} title={person.title} description={person.description} />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
5
src/components/ContactPerson/list.module.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
5
src/components/ContactPerson/styles.module.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
@import "template.scss";
|
||||
|
||||
.description {
|
||||
white-space: preserve;
|
||||
}
|
||||
|
|
@ -4,13 +4,13 @@ import classNames from 'classnames'
|
|||
type ContainerProps = {
|
||||
children: JSX.Element | JSX.Element[],
|
||||
flex?: boolean
|
||||
position?: "center" | "left" | "right"
|
||||
position?: "center" | "left" | "right",
|
||||
textAlign?: "left" | "center" | "right",
|
||||
}
|
||||
|
||||
export const Container = ({ children, flex = false, position = "center" }: ContainerProps) => {
|
||||
export const Container = ({ children, position = "center", textAlign="left" }: ContainerProps) => {
|
||||
return <div className={classNames({
|
||||
[styles.container]: true,
|
||||
[styles.flex]: flex,
|
||||
[styles.right]: position === "right",
|
||||
})}>{children}</div>
|
||||
})} style={{ textAlign }}>{children}</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,6 @@ $width: 1100px;
|
|||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
gap: 80px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.right {
|
||||
max-width: inherit;
|
||||
margin-left: calc((100vw - $width) / 2);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { useMemo } from 'react'
|
||||
import styles from "./styles.module.scss"
|
||||
import classNames from 'classnames'
|
||||
import Link from 'next/link'
|
||||
|
||||
type EventRowProps = {
|
||||
export type EventRowProps = {
|
||||
/** datetime 8601 format */
|
||||
date: string,
|
||||
title: string,
|
||||
|
|
@ -37,29 +38,31 @@ const shortMonth = (date: string) => {
|
|||
|
||||
|
||||
|
||||
export const EventRow = ({date, title, location, cancelled}: EventRowProps) => {
|
||||
export const EventRow = ({date, title, location, cancelled, href}: EventRowProps) => {
|
||||
const day = useMemo(() => date.substring(8, 10), [date]);
|
||||
const dateObj = useMemo(() => new Date(date), [date]);
|
||||
const month = useMemo(() => shortMonth(date), [date]);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.day}>
|
||||
{day} <br/>
|
||||
{month}
|
||||
</div>
|
||||
<Link href={href} className={styles.link}>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.day}>
|
||||
{day} <br />
|
||||
{month}
|
||||
</div>
|
||||
|
||||
<div className={styles.line}></div>
|
||||
<div className={styles.line}></div>
|
||||
|
||||
<div className={classNames({
|
||||
[styles.details]: true,
|
||||
[styles.cancelled]: cancelled
|
||||
<div className={classNames({
|
||||
[styles.details]: true,
|
||||
[styles.cancelled]: cancelled
|
||||
})}>
|
||||
{title} <br/>
|
||||
{dateObj.toLocaleDateString("de-DE", { weekday: "long"})} {dateObj.toLocaleDateString("de-DE", {dateStyle: "medium"})}, {dateObj.toLocaleTimeString("de-DE", {timeStyle: "short"})} Uhr
|
||||
<br/>
|
||||
{location}
|
||||
{title} <br />
|
||||
{dateObj.toLocaleDateString("de-DE", { weekday: "long" })} {dateObj.toLocaleDateString("de-DE", { dateStyle: "medium" })}, {dateObj.toLocaleTimeString("de-DE", { timeStyle: "short" })} Uhr
|
||||
<br />
|
||||
{location}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
|
@ -28,12 +28,17 @@
|
|||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.link {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.cancelled {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.container:hover .day {
|
||||
color: $shade1;
|
||||
color: $contrast-color;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 576px) {
|
||||
|
|
|
|||
14
src/components/Flex/Row.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import styles from "./styles.module.scss"
|
||||
|
||||
type RowProps = {
|
||||
children: React.ReactNode
|
||||
alignItems?: "center"
|
||||
}
|
||||
|
||||
export const Row = ({ children, alignItems }: RowProps) => {
|
||||
return (
|
||||
<div className={styles.row} style={{ alignItems: alignItems }}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,5 +1,12 @@
|
|||
.row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 80px;
|
||||
}
|
||||
|
||||
.col {
|
||||
width: calc(50% - 40px);
|
||||
flex: 1 1 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 576px) {
|
||||
|
|
|
|||
13
src/components/HorizontalRule/HorizontalRule.stories.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { HR } from './HorizontalRule'
|
||||
|
||||
const meta: Meta<typeof HR> = {
|
||||
component: HR,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof HR>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
}
|
||||
13
src/components/HorizontalRule/HorizontalRule.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import styles from "./styles.module.scss"
|
||||
import Image from "next/image"
|
||||
import cross from "./cross.svg"
|
||||
|
||||
export const HR = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.line}></div>
|
||||
<Image src={cross} alt={"Cross"} className={styles.cross} />
|
||||
<div className={styles.line}></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
31
src/components/HorizontalRule/cross.svg
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="40"
|
||||
height="70"
|
||||
viewBox="0 0 10.583333 18.520834"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#426156FF;stroke-width:0.473399"
|
||||
id="rect846"
|
||||
width="0.80836952"
|
||||
height="16.864483"
|
||||
x="5.1093903"
|
||||
y="0.83949941" />
|
||||
<rect
|
||||
style="fill:#426156FF;stroke-width:0.454843"
|
||||
id="rect848"
|
||||
width="10"
|
||||
height="0.7728833"
|
||||
x="0.35068181"
|
||||
y="4.9346447" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 712 B |
13
src/components/HorizontalRule/styles.module.scss
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
@import "template.scss";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
padding: 10px 5%;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.line {
|
||||
border-bottom: 1.5px solid $base-color;
|
||||
flex: 1 1 0;
|
||||
height: 35px;
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import styles from "./styles.module.scss"
|
||||
import { StaticImageData } from 'next/image'
|
||||
import Link from 'next/link'
|
||||
|
||||
type ImageCardProps = {
|
||||
export type ImageCardProps = {
|
||||
src: string | StaticImageData,
|
||||
title: string,
|
||||
href: string
|
||||
|
|
@ -9,10 +10,12 @@ type ImageCardProps = {
|
|||
|
||||
export const ImageCard = ({src, title, href}: ImageCardProps) => {
|
||||
return (
|
||||
<div className={styles.container} style={{backgroundImage: `url(${src})`}}>
|
||||
<div className={styles.title}>
|
||||
{title}
|
||||
<Link href={href}>
|
||||
<div className={styles.container} style={{ backgroundImage: `url(${src})` }}>
|
||||
<div className={styles.title}>
|
||||
{title}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
|
@ -4,12 +4,13 @@ type InputProps = {
|
|||
name: string;
|
||||
type: 'textarea' | 'text' | 'email'
|
||||
placeholder?: string
|
||||
rows?: number
|
||||
}
|
||||
|
||||
export const Input = ({name, type, placeholder}: InputProps) => {
|
||||
export const Input = ({name, type, placeholder, rows = 5}: InputProps) => {
|
||||
if (type === 'textarea') {
|
||||
return (
|
||||
<textarea name={name} className={styles.input} placeholder={placeholder}>
|
||||
<textarea name={name} className={styles.input} placeholder={placeholder} rows={rows}>
|
||||
|
||||
</textarea>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
@media screen and (max-width: 576px) {
|
||||
.input {
|
||||
padding: 5px 10px;
|
||||
font-size: 16px;
|
||||
padding: 10px 15px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
3
src/components/Margin/MarbinBottom.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const MarginBottom = () => {
|
||||
return <div style={{marginBottom: "70px"}}></div>
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import { MassTableRow } from '@/components/MassTable/MassTableRow'
|
||||
import { useMemo } from 'react'
|
||||
import styles from './styles.module.css'
|
||||
import { faustina } from '@/app/fonts'
|
||||
import { Worship } from '@/payload-types'
|
||||
import { useCompactDate } from '@/hooks/useCompactDate'
|
||||
import { ChurchCard } from '@/components/ChurchCard/ChurchCard'
|
||||
import { church } from '@/utils/church'
|
||||
|
||||
type MassTableProps = {
|
||||
location: string
|
||||
|
|
@ -18,6 +18,10 @@ export const MassTable = ({ location, masses }: MassTableProps) => {
|
|||
{location}
|
||||
</h3>
|
||||
|
||||
<div className={styles.church}>
|
||||
<ChurchCard church={church(location)} backgroundColor={"#fffff"} width={200} />
|
||||
</div>
|
||||
|
||||
{masses.map((mass) => (
|
||||
<MassTableRow
|
||||
key={mass.id}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export const MassTableRow = ({
|
|||
|
||||
return (
|
||||
<Link
|
||||
href={`/worship/${id}`}
|
||||
href={`/gottesdienst/${id}`}
|
||||
className={classNames({ [styles.cancelled]: cancelled }, styles.link)}
|
||||
>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -28,3 +28,7 @@
|
|||
width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.church {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
|
|
|||
157
src/components/MegaMenu/MegaMenu.stories.tsx
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { MegaMenu } from './MegaMenu'
|
||||
|
||||
const meta: Meta<typeof MegaMenu> = {
|
||||
component: MegaMenu,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof MegaMenu>;
|
||||
export default meta
|
||||
|
||||
export const TwoColumns: Story = {
|
||||
args: {
|
||||
bibleText: "Ich will den HERRN loben allezeit; sein Lob soll immerdar in meinem Munde sein. Meine Seele soll sich rühmen des HERRN, dass es die Elenden hören und sich freuen.",
|
||||
bibleBook: "Psalm 34 2,3",
|
||||
groups: [
|
||||
{
|
||||
title: "Sakramenten",
|
||||
items: [
|
||||
{
|
||||
title: "Taufe",
|
||||
description: "Neues Leben in Christus",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Eucharistie",
|
||||
description: "Gemeinschaft durch Brot und Wein",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Firmung",
|
||||
description: "Stärkung im Heiligen Geist",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Ehe",
|
||||
description: "Bund in Liebe, Treue",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Beichte",
|
||||
description: "Sündenbekenntnis, Vergebung und Neuanfang mit Gottes Gnade",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Krankensalbung",
|
||||
description: "Stärkung und Gottes Beistand",
|
||||
href: "https://"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
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://"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
export const ThreeColumns = {
|
||||
args: {
|
||||
bibleText: "„Denn wo zwei oder drei in meinem Namen versammelt sind, da bin ich mitten unter ihnen.“",
|
||||
bibleBook: "Jacc 45",
|
||||
groups: [
|
||||
{
|
||||
title: "Gemeinden",
|
||||
items: [
|
||||
{
|
||||
title: "St. Richard",
|
||||
description: "Mehr informationen",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "St. Christophorus",
|
||||
description: "Mehr informationen",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "St. Clara",
|
||||
description: "Mehr informationen",
|
||||
href: "https://"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
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://"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
64
src/components/MegaMenu/MegaMenu.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import styles from "./styles.module.scss"
|
||||
import { faustina } from '@/app/fonts'
|
||||
import Link from 'next/link'
|
||||
|
||||
type MegaMenuProps = {
|
||||
bibleText: string,
|
||||
bibleBook: string,
|
||||
groups: ItemGroupProps[],
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
type ItemProps = {
|
||||
title: string;
|
||||
description: string
|
||||
href: string
|
||||
}
|
||||
|
||||
type ItemGroupProps = {
|
||||
title: string,
|
||||
items: ItemProps[]
|
||||
}
|
||||
|
||||
const Item = ({href, title, description}: ItemProps) => {
|
||||
return (
|
||||
<Link href={href} className={styles.item}>
|
||||
<div className={styles.itemIcon}>
|
||||
</div>
|
||||
<div>
|
||||
<div className={styles.itemTitle}>
|
||||
{title}
|
||||
</div>
|
||||
<div className={styles.itemDescription}>
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
const ItemGroup = ({title, items}: ItemGroupProps) => {
|
||||
return (
|
||||
<div className={styles.itemGroup}>
|
||||
<div className={styles.groupTitle}>{title}</div>
|
||||
{items.map(item => <Item key={item.title} title={item.title} href={item.href} description={item.description} />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProps) => {
|
||||
return (
|
||||
<div className={styles.menu} onClick={onClick}>
|
||||
<div className={styles.bibleText}>
|
||||
<div className={faustina.className}>
|
||||
{bibleText}
|
||||
</div>
|
||||
<div className={styles.book}>
|
||||
{bibleBook}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{groups.map(group => <ItemGroup key={group.title} title={group.title} items={group.items} />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
71
src/components/MegaMenu/styles.module.scss
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
@import "template.scss";
|
||||
|
||||
$width: 220px;
|
||||
|
||||
.menu {
|
||||
background-color: $shade3;
|
||||
display: inline-flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.bibleText {
|
||||
background-color: $base-color;
|
||||
color: $shade3;
|
||||
width: 200px;
|
||||
font-size: 24px;
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.book {
|
||||
text-align: right;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.itemIcon {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 13px;
|
||||
border: 1px solid $base-color;
|
||||
box-shadow: 3px 7px 26px -5px rgba(0, 0, 0, 0.15);
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.itemGroup {
|
||||
padding: 40px;
|
||||
width: $width;
|
||||
}
|
||||
|
||||
.groupTitle {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
margin: 25px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item:hover .itemIcon {
|
||||
background-color: $base-color;
|
||||
}
|
||||
|
||||
.itemTitle {
|
||||
font-size: 18px;
|
||||
line-height: 120%;
|
||||
}
|
||||
|
||||
.itemDescription {
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
line-height: 95%;
|
||||
}
|
||||
|
|
@ -1,40 +1,220 @@
|
|||
"use client"
|
||||
|
||||
import styles from './styles.module.scss'
|
||||
import MenuIcon from './menu.svg'
|
||||
import Image from 'next/image'
|
||||
import classNames from 'classnames'
|
||||
import { useState } from 'react'
|
||||
import { MegaMenu } from '@/components/MegaMenu/MegaMenu'
|
||||
|
||||
|
||||
export const Menu = () => {
|
||||
return (
|
||||
<nav className={classNames(styles.nav)}>
|
||||
<div className={styles.navMobile}>
|
||||
<Image src={MenuIcon} width={25} height={25} alt={'Menu'} />
|
||||
</div>
|
||||
<div className={styles.itemsLeft}>
|
||||
<a className={styles.menuLink} href={'/'}>
|
||||
Home
|
||||
</a>
|
||||
<a className={styles.menuLink} href={''}>
|
||||
Gemeinschaft finden
|
||||
</a>
|
||||
<a className={styles.menuLink} href={''}>
|
||||
Glauben leben
|
||||
</a>
|
||||
<a className={styles.menuLink} href={''}>
|
||||
Kontakt
|
||||
</a>
|
||||
</div>
|
||||
const [displayMenu2, setDisplayMenu2] = useState(false);
|
||||
const [displayMenu1, setDisplayMenu1] = useState(false);
|
||||
|
||||
<div className={styles.itemsRight}>
|
||||
<div>
|
||||
<a className={styles.menuLink} href={''}>
|
||||
Mithelfen
|
||||
|
||||
const displayFirstMenu = () => {
|
||||
setDisplayMenu1(true);
|
||||
setDisplayMenu2(false);
|
||||
}
|
||||
|
||||
const displaySecondMenu = () => {
|
||||
setDisplayMenu2(true)
|
||||
setDisplayMenu1(false)
|
||||
}
|
||||
|
||||
const displayNothing = () => {
|
||||
setDisplayMenu1(false);
|
||||
setDisplayMenu2(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className={classNames(styles.nav)}>
|
||||
<div className={styles.navMobile}>
|
||||
<Image src={MenuIcon} width={25} height={25} alt={'Menu'} />
|
||||
</div>
|
||||
<div className={styles.itemsLeft}>
|
||||
<a className={styles.menuLink} href={'/'} onMouseEnter={displayNothing}>
|
||||
Home
|
||||
</a>
|
||||
<a className={styles.menuLink} href={''} onMouseEnter={displayFirstMenu}>
|
||||
Gemeinschaft finden
|
||||
</a>
|
||||
<a className={styles.menuLink} href={''} onMouseEnter={displaySecondMenu}>
|
||||
Glauben leben
|
||||
</a>
|
||||
<a className={styles.menuLink} href={''} onMouseEnter={displayNothing}>
|
||||
Kontakt
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<button className={styles.button}>Neu hier?</button>
|
||||
|
||||
<div className={styles.itemsRight}>
|
||||
<div>
|
||||
<a className={styles.menuLink} href={''}>
|
||||
Mithelfen
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<button className={styles.button}>Neu hier?</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div
|
||||
className={styles.megaMenu}
|
||||
style={{ display: displayMenu2 ? 'block' : 'none', opacity: displayMenu2 ? 1 : 0 }}
|
||||
onMouseLeave={() => setDisplayMenu2(false)}
|
||||
>
|
||||
<MegaMenu
|
||||
bibleText={"Ich will den HERRN loben allezeit; sein Lob soll immerdar in meinem Munde sein. Meine Seele soll sich rühmen des HERRN, dass es die Elenden hören und sich freuen."}
|
||||
bibleBook={"Psalm 34 2,3"}
|
||||
onClick={() => setDisplayMenu2(false)}
|
||||
groups={[
|
||||
{
|
||||
title: "Sakramenten",
|
||||
items: [
|
||||
{
|
||||
title: "Taufe",
|
||||
description: "Neues Leben in Christus",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Eucharistie",
|
||||
description: "Gemeinschaft durch Brot und Wein",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Firmung",
|
||||
description: "Stärkung im Heiligen Geist",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Ehe",
|
||||
description: "Bund in Liebe, Treue",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Beichte",
|
||||
description: "Sündenbekenntnis, Vergebung und Neuanfang mit Gottes Gnade",
|
||||
href: "https://"
|
||||
},
|
||||
{
|
||||
title: "Krankensalbung",
|
||||
description: "Stärkung und Gottes Beistand",
|
||||
href: "https://"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
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://"
|
||||
},
|
||||
]
|
||||
}
|
||||
]} />
|
||||
</div>
|
||||
</nav>
|
||||
<div
|
||||
className={styles.megaMenu}
|
||||
style={{ display: displayMenu1 ? 'block' : 'none', opacity: displayMenu1 ? 1 : 0 }}
|
||||
onMouseLeave={() => setDisplayMenu1(false)}
|
||||
>
|
||||
<MegaMenu
|
||||
bibleText={"„Denn wo zwei oder drei in meinem Namen versammelt sind, da bin ich mitten unter ihnen.“"}
|
||||
bibleBook={"Matt 18-2"}
|
||||
onClick={() => setDisplayMenu1(false)}
|
||||
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://"
|
||||
},
|
||||
]
|
||||
}
|
||||
]} />
|
||||
</div>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.megaMenu {
|
||||
position: fixed;
|
||||
top: 76px;
|
||||
z-index: 8;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.navMobile {
|
||||
display: block;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import classNames from 'classnames'
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
export type BackgroundColor = "soft" | undefined
|
||||
export type BackgroundColor = "soft" | "off-white" | undefined
|
||||
|
||||
type SectionProps = {
|
||||
backgroundColor?: BackgroundColor
|
||||
|
|
@ -12,7 +12,8 @@ export const Section = ({ children, backgroundColor }: SectionProps) => {
|
|||
return (
|
||||
<section className={classNames({
|
||||
[styles.section]: true,
|
||||
[styles.shade2]: backgroundColor === "soft"
|
||||
[styles.shade2]: backgroundColor === "soft",
|
||||
[styles.shade3]: backgroundColor === "off-white"
|
||||
})}>
|
||||
{children}
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
background-color: $shade2;
|
||||
}
|
||||
|
||||
.shade3 {
|
||||
background-color: $shade3;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 576px) {
|
||||
.section {
|
||||
padding: 70px 0;
|
||||
|
|
|
|||
11
src/components/Text/TextDiv.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
type TextProps = {
|
||||
text: string
|
||||
}
|
||||
|
||||
export const TextDiv = ({text}: TextProps) => {
|
||||
return (
|
||||
<div style={{whiteSpace: 'preserve'}}>
|
||||
{text}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -14,6 +14,20 @@ export const Default: Story = {
|
|||
},
|
||||
}
|
||||
|
||||
export const WithSubtitle: Story = {
|
||||
args: {
|
||||
title: 'Wahlfahrt Lourdes',
|
||||
subtitle: "Sei dabei!"
|
||||
},
|
||||
}
|
||||
|
||||
export const Contrast: Story = {
|
||||
args: {
|
||||
title: 'Aktuelles',
|
||||
color: "contrast"
|
||||
},
|
||||
}
|
||||
|
||||
export const BigTitle: Story = {
|
||||
args: {
|
||||
title: 'Veranstaltungen',
|
||||
|
|
|
|||
|
|
@ -4,21 +4,43 @@ import { faustina } from '@/app/fonts'
|
|||
|
||||
type TitleProps = {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
align?: 'left' | 'center';
|
||||
size?: 'xl' | 'lg' | 'md';
|
||||
size?: 'xl' | 'lg' | 'md' | "sm";
|
||||
fontStyle?: 'serif' | 'sans-serif'
|
||||
color?: "base" | "contrast" | "white"
|
||||
}
|
||||
|
||||
export const Title = ({title, align = "left", size = "lg", fontStyle = "serif"}: TitleProps) => {
|
||||
export const Title = ({title, subtitle, align = "left", size = "lg", fontStyle = "serif", color = "base"}: TitleProps) => {
|
||||
return (
|
||||
<h2 className={classNames({
|
||||
[styles.title]: true,
|
||||
[styles.extraLarge]: size === "xl",
|
||||
[styles.large]: size === "lg",
|
||||
[styles.medium]: size === "md",
|
||||
[styles.left]: align === "left",
|
||||
[styles.center]: align === "center",
|
||||
[faustina.className]: fontStyle == "serif",
|
||||
})}>{title}</h2>
|
||||
<>
|
||||
<h2 className={classNames({
|
||||
[styles.title]: true,
|
||||
[styles.base]: color === "base",
|
||||
[styles.contrast]: color === "contrast",
|
||||
[styles.white]: color === "white",
|
||||
[styles.extraLarge]: size === "xl",
|
||||
[styles.large]: size === "lg",
|
||||
[styles.medium]: size === "md",
|
||||
[styles.small]: size === "sm",
|
||||
[styles.left]: align === "left",
|
||||
[styles.center]: align === "center",
|
||||
[faustina.className]: fontStyle == "serif",
|
||||
})}>{title}</h2>
|
||||
{subtitle &&
|
||||
<div className={classNames({
|
||||
[styles.subtitle]: true,
|
||||
[styles.base]: color === "contrast",
|
||||
[styles.contrast]: color === "base",
|
||||
[styles.white]: color === "white",
|
||||
[styles.small]: true,
|
||||
[styles.left]: align === "left",
|
||||
[styles.center]: align === "center",
|
||||
[faustina.className]: fontStyle == "sans-serif"
|
||||
})}>
|
||||
{subtitle}
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,8 +1,26 @@
|
|||
@import "template.scss";
|
||||
|
||||
.title {
|
||||
color: $base-color;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
position: relative;
|
||||
top: -30px;
|
||||
}
|
||||
|
||||
.base {
|
||||
color: $base-color;
|
||||
}
|
||||
|
||||
.contrast {
|
||||
color: $contrast-color;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.extraLarge {
|
||||
|
|
@ -20,6 +38,12 @@
|
|||
font-weight: 700;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 25px;
|
||||
font-weight: 700;
|
||||
margin: 10px 0 5px 0;
|
||||
}
|
||||
|
||||
.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
|
@ -40,4 +64,8 @@
|
|||
.medium {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
31
src/compositions/ChurchWithContact/ChurchWithContact.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { Col } from '@/components/Flex/Col'
|
||||
import styles from '@/pageComponents/Parish/styles.module.scss'
|
||||
import { ChurchCard } from '@/components/ChurchCard/ChurchCard'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { TextDiv } from '@/components/Text/TextDiv'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { church as transform } from '@/utils/church'
|
||||
|
||||
type ChurchWithContactProps = {
|
||||
church: string,
|
||||
contact: string
|
||||
}
|
||||
|
||||
export const ChurchWithContact = ({church, contact}: ChurchWithContactProps) => {
|
||||
const c = transform(church)
|
||||
|
||||
|
||||
return (
|
||||
<Row alignItems={"center"}>
|
||||
<Col>
|
||||
<div className={styles.churchIcon}>
|
||||
<ChurchCard church={c} backgroundColor={'#E0DAE5'} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col>
|
||||
<Title title={"Kontakt"} size={"md"} color={"contrast"} />
|
||||
<TextDiv text={contact} />
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
|
@ -2,29 +2,30 @@ 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'
|
||||
|
||||
type Col50Props = {
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const Col50 = ({children}: Col50Props) => {
|
||||
return <div>{children}</div>
|
||||
}
|
||||
|
||||
export const ContactSection = () => {
|
||||
return (
|
||||
<Section>
|
||||
<Container flex={true}>
|
||||
<Col50>
|
||||
<Title title="Kontakt" size={"lg"} />
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacinia efficitur sapien, vel molestie ligula fermentum rutrum. Maecenas vel mattis leo. Donec dictum convallis mi ac fermentum. Praesent imperdiet dictum arcu, vel lacinia est accumsan ut. Mauris ultrices leo ut mi eleifend, at porttitor mauris condimentum. Quisque a viverra tellus. Cras eu euismod augue. Morbi tristique a nisi vitae tincidunt. Nullam eget dignissim risus, ut tempor nulla. Proin suscipit mi sed leo posuere scelerisque. Sed vel semper ligula.
|
||||
</p>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<Title title="Kontakt" size={"lg"} />
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacinia efficitur sapien, vel molestie ligula fermentum rutrum. Maecenas vel mattis leo. Donec dictum convallis mi ac fermentum. Praesent imperdiet dictum arcu, vel lacinia est accumsan ut. Mauris ultrices leo ut mi eleifend, at porttitor mauris condimentum. Quisque a viverra tellus. Cras eu euismod augue. Morbi tristique a nisi vitae tincidunt. Nullam eget dignissim risus, ut tempor nulla. Proin suscipit mi sed leo posuere scelerisque. Sed vel semper ligula.
|
||||
</p>
|
||||
|
||||
</Col50>
|
||||
<Col50>
|
||||
<ContactForm />
|
||||
</Col50>
|
||||
</Col>
|
||||
<Col>
|
||||
<ContactForm />
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
|
|
|
|||
66
src/compositions/Events/Events.stories.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Events } from './Events'
|
||||
|
||||
const meta: Meta<typeof Events> = {
|
||||
component: Events,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof Events>;
|
||||
export default meta
|
||||
|
||||
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"
|
||||
},
|
||||
],
|
||||
n: 3
|
||||
},
|
||||
}
|
||||
70
src/compositions/Events/Events.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"use client"
|
||||
import { EventRow, EventRowProps } from '@/components/EventRow/EventRow'
|
||||
import { useMemo, useState } from 'react'
|
||||
import styles from "./events.module.scss"
|
||||
|
||||
type EventsProps = {
|
||||
/**
|
||||
* All the events
|
||||
*/
|
||||
events: EventRowProps[],
|
||||
|
||||
/**
|
||||
* Display `n` number of events per
|
||||
* page
|
||||
*/
|
||||
n: number,
|
||||
}
|
||||
|
||||
export const Events = ({ events, n }: EventsProps) => {
|
||||
|
||||
const [page, setPage] = useState<number>(0)
|
||||
const eventsPerPage = useMemo(() => {
|
||||
return events.slice(n * page, n * (page+1))
|
||||
}, [events, page, n])
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
eventsPerPage.map(event =>
|
||||
<EventRow
|
||||
key={event.href}
|
||||
date={event.date}
|
||||
title={event.title}
|
||||
href={event.href}
|
||||
location={event.location}
|
||||
cancelled={event.cancelled}
|
||||
/>,
|
||||
)}
|
||||
|
||||
<div className={styles.buttons}>
|
||||
<button
|
||||
type={"button"}
|
||||
disabled={page === 0}
|
||||
className={styles.button}
|
||||
onClick={() => setPage(page - 1)}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="30px"
|
||||
width="30px" version="1.1" id="Layer_1" viewBox="0 0 330 330">
|
||||
<path id="XMLID_6_"
|
||||
d="M165,0C74.019,0,0,74.019,0,165s74.019,165,165,165s165-74.019,165-165S255.981,0,165,0z M205.606,234.394 c5.858,5.857,5.858,15.355,0,21.213C202.678,258.535,198.839,260,195,260s-7.678-1.464-10.606-4.394l-80-79.998 c-2.813-2.813-4.394-6.628-4.394-10.606c0-3.978,1.58-7.794,4.394-10.607l80-80.002c5.857-5.858,15.355-5.858,21.213,0 c5.858,5.857,5.858,15.355,0,21.213l-69.393,69.396L205.606,234.394z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
type={"button"}
|
||||
disabled={n * (page + 1) >= events.length} onClick={() => setPage(page + 1)}
|
||||
className={styles.button}
|
||||
>
|
||||
<svg fill="#000000" height="30px" width="30px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 330 330">
|
||||
<path id="XMLID_2_" d="M165,0C74.019,0,0,74.019,0,165s74.019,165,165,165s165-74.019,165-165S255.981,0,165,0z M225.606,175.605
|
||||
l-80,80.002C142.678,258.535,138.839,260,135,260s-7.678-1.464-10.606-4.394c-5.858-5.857-5.858-15.355,0-21.213l69.393-69.396
|
||||
l-69.393-69.392c-5.858-5.857-5.858-15.355,0-21.213c5.857-5.858,15.355-5.858,21.213,0l80,79.998
|
||||
c2.814,2.813,4.394,6.628,4.394,10.606C230,168.976,228.42,172.792,225.606,175.605z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
28
src/compositions/Events/events.module.scss
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
@import "template.scss";
|
||||
|
||||
.button {
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button svg {
|
||||
fill: $shade2;
|
||||
}
|
||||
|
||||
.button:hover svg {
|
||||
fill: $base-color;
|
||||
}
|
||||
|
||||
.button:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.button:disabled:hover svg {
|
||||
fill: $shade2;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding-left: 130px;
|
||||
}
|
||||
|
|
@ -2,29 +2,38 @@ 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'
|
||||
|
||||
|
||||
export const Footer = () => {
|
||||
return (
|
||||
<Section backgroundColor="soft">
|
||||
<Container flex={true}>
|
||||
<Logo
|
||||
color={"#ffffff"}
|
||||
textColor={"#426156"}
|
||||
withText={true}
|
||||
height={120}
|
||||
/>
|
||||
<div className={styles.container}>
|
||||
<p>
|
||||
Briesestraße 17 <br/>
|
||||
12053 Berlin-Neukölln
|
||||
</p>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<Logo
|
||||
color={"#ffffff"}
|
||||
textColor={"#426156"}
|
||||
withText={true}
|
||||
height={120}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<p>
|
||||
T: 030-6889120 <br/>
|
||||
E: pfarrer@dreikoenige.berlin
|
||||
</p>
|
||||
</div>
|
||||
<Col>
|
||||
<div className={styles.container}>
|
||||
<p>
|
||||
Briesestraße 17 <br />
|
||||
12053 Berlin-Neukölln
|
||||
</p>
|
||||
|
||||
<p>
|
||||
T: 030-6889120 <br />
|
||||
E: pfarrer@dreikoenige.berlin
|
||||
</p>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import styles from "./styles.module.scss"
|
|||
import { StaticImageData } from 'next/image'
|
||||
import { Arrow } from '@/components/Arrow/Arrow'
|
||||
|
||||
type Slide = {
|
||||
export type Slide = {
|
||||
id: string,
|
||||
src: string | StaticImageData,
|
||||
title: string,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import forest from "./forest.jpeg"
|
||||
import chris from "./christophorus.jpeg"
|
||||
import forest from "../../assets/forest.jpeg"
|
||||
import chris from "../../assets/christophorus.jpeg"
|
||||
import { ImageWithText } from './ImageWithText'
|
||||
import { Button } from '@/components/Button/Button'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { BackgroundColor, Section } from '@/components/Section/Section'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { Button } from '@/components/Button/Button'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import Image, { StaticImageData } from 'next/image'
|
||||
import styles from "./styles.module.scss"
|
||||
import classNames from 'classnames'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
|
||||
type ImageWithTextProps = {
|
||||
backgroundColor?: BackgroundColor,
|
||||
|
|
@ -15,27 +15,30 @@ type ImageWithTextProps = {
|
|||
}
|
||||
|
||||
export const ImageWithText = ({backgroundColor, title, image, text, link}: ImageWithTextProps) => {
|
||||
console.log(image)
|
||||
return (
|
||||
<Section backgroundColor={backgroundColor}>
|
||||
<Container flex={true}>
|
||||
<div className={classNames(styles.col, styles.imageCol)}>
|
||||
<Image className={styles.image} src={image} objectFit={"cover"} alt={""} />
|
||||
</div>
|
||||
<div className={styles.col}>
|
||||
<Title title={title} size={"lg"} />
|
||||
|
||||
<Image className={styles.imageMobile} src={image} objectFit={"cover"} alt={""} />
|
||||
|
||||
<div>
|
||||
{text}
|
||||
<Container>
|
||||
<Row alignItems={"center"}>
|
||||
<div className={classNames(styles.col, styles.imageCol)}>
|
||||
<Image className={styles.image} width={800} height={800} src={image} objectFit={"cover"} alt={""} />
|
||||
</div>
|
||||
<div className={styles.col}>
|
||||
<Title title={title} size={"lg"} />
|
||||
|
||||
{link &&
|
||||
<div className={styles.right}>
|
||||
{link}
|
||||
<Image className={styles.imageMobile} width={500} height={500} src={image} objectFit={"cover"} alt={""} />
|
||||
|
||||
<div>
|
||||
{text}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
{link &&
|
||||
<div className={styles.right}>
|
||||
{link}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
)
|
||||
|
|
|
|||
21
src/fetch/blog.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { Blog } from '@/payload-types'
|
||||
import { PaginatedDocs } from 'payload'
|
||||
import { stringify } from 'qs-esm'
|
||||
|
||||
export const fetchBlog = async (): Promise<PaginatedDocs<Blog> | undefined> => {
|
||||
const stringifiedQuery = stringify(
|
||||
{
|
||||
sort: "-date",
|
||||
select: {
|
||||
title: true,
|
||||
date: true,
|
||||
photo: true
|
||||
}
|
||||
},
|
||||
{ addQueryPrefix: true },
|
||||
)
|
||||
|
||||
const resp = await fetch(`http://localhost:3000/api/blog`);
|
||||
if (!resp.ok) return undefined;
|
||||
return resp.json();
|
||||
}
|
||||
46
src/fetch/events.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { stringify } from 'qs-esm'
|
||||
import { PaginatedDocs } from 'payload'
|
||||
import { Event } from '@/payload-types'
|
||||
|
||||
/**
|
||||
* Fetch a list of events
|
||||
*
|
||||
*/
|
||||
export async function fetchEvents(parishId: string | undefined): Promise<PaginatedDocs<Event> | undefined> {
|
||||
const date = new Date()
|
||||
|
||||
const query: any = {
|
||||
and: [
|
||||
{
|
||||
date: {
|
||||
greater_than_equal: date.toISOString(),
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
if (parishId) {
|
||||
query.and.push({
|
||||
"parish": {
|
||||
equals: parishId
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const stringifiedQuery = stringify(
|
||||
{
|
||||
sort: "date",
|
||||
where: query,
|
||||
select: {
|
||||
location: true,
|
||||
date: true,
|
||||
title: true
|
||||
}
|
||||
},
|
||||
{ addQueryPrefix: true },
|
||||
)
|
||||
|
||||
const response = await fetch(`http://localhost:3000/api/event${stringifiedQuery}`)
|
||||
if (!response.ok) return undefined
|
||||
return response.json()
|
||||
}
|
||||
45
src/fetch/worship.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { stringify } from 'qs-esm'
|
||||
import { PaginatedDocs } from 'payload'
|
||||
import { Worship } from '@/payload-types'
|
||||
|
||||
export const fetchWorship = async (locations?: string[]): Promise<PaginatedDocs<Worship> | undefined> => {
|
||||
const date = new Date();
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
||||
const query: any = {
|
||||
and: [
|
||||
{
|
||||
date: {
|
||||
greater_than_equal: date.toISOString(),
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
if (locations ) {
|
||||
query.and.push({
|
||||
location: {
|
||||
in: locations
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const stringifiedQuery = stringify(
|
||||
{
|
||||
sort: "date",
|
||||
where: query,
|
||||
select: {
|
||||
type: true,
|
||||
date: true,
|
||||
cancelled: true,
|
||||
location: true
|
||||
},
|
||||
limit: 15
|
||||
},
|
||||
{ addQueryPrefix: true },
|
||||
)
|
||||
|
||||
const response = await fetch(`http://localhost:3000/api/worship${stringifiedQuery}`)
|
||||
if (!response.ok) return undefined
|
||||
return response.json()
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import { calendar } from '@/hooks/calendars'
|
|||
* Return liturgical name of the date
|
||||
* e.G. "2024-12-25" => Christmas
|
||||
*/
|
||||
export const useLiturgyCalendarTitle = (date: string) => {
|
||||
export const liturgicalDayName = (date: string) => {
|
||||
const day = calendar[date.substring(0, 10)]
|
||||
return day.name
|
||||
}
|
||||
24
src/pageComponents/Home/Home.stories.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
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/>
|
||||
<Story />
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof Home>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
}
|
||||
72
src/pageComponents/Home/Home.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
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 { Title } from '@/components/Title/Title'
|
||||
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 { Events } from '@/compositions/Events/Events'
|
||||
import { ImageWithText } from '@/compositions/ImageWithText/ImageWithText'
|
||||
|
||||
export const Home = () => {
|
||||
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>
|
||||
<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"
|
||||
}
|
||||
]} />
|
||||
</Section>
|
||||
</Container>
|
||||
|
||||
<ContentWithSlider slider={<>
|
||||
<Title title={"Akutelle Highlights"} size={"md"} fontStyle={"sans-serif"} color={"white"} />
|
||||
</>}>
|
||||
<Container position={"right"}>
|
||||
<Section>
|
||||
<Title title={"Veranstaltungen"} />
|
||||
</Section>
|
||||
</Container>
|
||||
</ContentWithSlider>
|
||||
|
||||
<ImageWithText
|
||||
image={forest}
|
||||
title={"Über uns"}
|
||||
text={"yolo"}
|
||||
backgroundColor={"soft"}
|
||||
/>
|
||||
|
||||
<ContactSection />
|
||||
</>
|
||||
)
|
||||
}
|
||||
65
src/pageComponents/Parish/Parish.stories.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import chris from "../../assets/christophorus.jpeg"
|
||||
import { Parish } from './Parish'
|
||||
import { Menu } from '@/components/Menu/Menu'
|
||||
import { Footer } from '@/compositions/Footer/Footer'
|
||||
|
||||
const meta: Meta<typeof Parish> = {
|
||||
component: Parish,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<>
|
||||
<Menu/>
|
||||
<Story />
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof Parish>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: "St. Christophorus",
|
||||
image: chris,
|
||||
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:
|
||||
|
||||
Eine neue katholische Kirche in Neukölln.
|
||||
|
||||
Den eifrigen Bemühungen des hochw. Herrn Pfarrers Trawnik ist es endlich gelungen, den Plan einer neuen Kirche am schönen Reuterplatz in Neukölln zu verwirklichen. Der Krieg hatte bisher den Kirchbau verhindert, obwohl die Vorbereitungen dazu beendet waren. Die Bank, welche den Bau finanzieren wollte, durfte im Juni 1914 die Bausumme nicht hergeben, weil sie zum Kriegführen benötigt wurde. Nun endlich soll es Wahrheit werden, es wird ein stattliches Gotteshaus erstehen, und sein Turm wird himmelan weisen.
|
||||
|
||||
Durch die sprunghafte Entwicklung Neuköllns hat die Gemeinde rapide an Ausdehnung gewonnen. Das rasche Wachstum der Einwohnerzahl hatte zur Folge, daß die Mietskasernen wie Pilze aus der Erde schossen.
|
||||
`,
|
||||
contactPersons: [
|
||||
{
|
||||
title: "Seelsorgeteam",
|
||||
description: `Pater Karl Hermann Lenz SAC (Pfarrvikar)
|
||||
pallottis@christophorus-berlin.de
|
||||
Lissy Eichert UAC
|
||||
l.eichert@christophorus-berlin.
|
||||
`
|
||||
},
|
||||
{
|
||||
title: "Pallottinische Gemeinschaft",
|
||||
description: `Lissy Eichert UAC
|
||||
l.eichert@christophorus-berlin.de`
|
||||
},
|
||||
{
|
||||
title: "Kirechenvorstand",
|
||||
description: "Some contactinfo"
|
||||
}
|
||||
],
|
||||
contact: `Nansenstraße 4-7
|
||||
12047 Berlin
|
||||
|
||||
Tel. 6 27 30 69-210
|
||||
Fax 6 27 30 69-299
|
||||
pfarramt@christophorus-berlin.de
|
||||
|
||||
Bürozeiten:
|
||||
Freitags 09:00 - 12:00 Uhr `
|
||||
}
|
||||
};
|
||||
75
src/pageComponents/Parish/Parish.tsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { ImageWithText } from '@/compositions/ImageWithText/ImageWithText'
|
||||
import { StaticImageData } from 'next/image'
|
||||
import { Section } from '@/components/Section/Section'
|
||||
import { Row } from '@/components/Flex/Row'
|
||||
import { Col } from '@/components/Flex/Col'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { TwoColumnText } from '@/components/TwoColumnText/TwoColumnText'
|
||||
import { Events } from '@/compositions/Events/Events'
|
||||
import { MarginBottom } from '@/components/Margin/MarbinBottom'
|
||||
import { ContactPersonList } from '@/components/ContactPerson/ContactPersonList'
|
||||
import { Event, Worship } from '@/payload-types'
|
||||
import { transformEvents } from '@/utils/dto/events'
|
||||
import { ChurchWithContact } from '@/compositions/ChurchWithContact/ChurchWithContact'
|
||||
import { tranformWorship } from '@/utils/dto/worship'
|
||||
|
||||
type ParishProps = {
|
||||
title: string,
|
||||
slug: string,
|
||||
image: string | StaticImageData,
|
||||
description: string,
|
||||
history: string
|
||||
contactPersons: {
|
||||
title: string,
|
||||
description: string
|
||||
}[],
|
||||
contact: string
|
||||
events: Event[],
|
||||
worship: Worship[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const Parish = ({title, slug, image, description, history, contactPersons, contact, events, worship}: ParishProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ImageWithText title={title} image={image} text={description} />
|
||||
|
||||
<Section>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<Title title={"Veranstaltungen"} size={"md"}/>
|
||||
<Events events={transformEvents(events)} n={4}/>
|
||||
|
||||
<MarginBottom />
|
||||
|
||||
<Title title={"Gottesdienste"} size={"md"} />
|
||||
<Events events={tranformWorship(worship)} n={4}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<Title title={"Ansprechpersonen"} size={"md"} />
|
||||
|
||||
<ContactPersonList persons={contactPersons} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
<Section backgroundColor={"soft"}>
|
||||
<Container>
|
||||
<Title title={"Unsere Geschichte"} />
|
||||
<TwoColumnText text={history} />
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<Container>
|
||||
<ChurchWithContact church={title} contact={contact} />
|
||||
</Container>
|
||||
</Section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
10
src/pageComponents/Parish/styles.module.scss
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.churchIcon {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 576px) {
|
||||
.churchIcon {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,17 +24,42 @@ export interface Config {
|
|||
page: Page;
|
||||
users: User;
|
||||
media: Media;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
parish: ParishSelect<false> | ParishSelect<true>;
|
||||
church: ChurchSelect<false> | ChurchSelect<true>;
|
||||
worship: WorshipSelect<false> | WorshipSelect<true>;
|
||||
vermeldungen: VermeldungenSelect<false> | VermeldungenSelect<true>;
|
||||
blog: BlogSelect<false> | BlogSelect<true>;
|
||||
tweet: TweetSelect<false> | TweetSelect<true>;
|
||||
event: EventSelect<false> | EventSelect<true>;
|
||||
group: GroupSelect<false> | GroupSelect<true>;
|
||||
employees: EmployeesSelect<false> | EmployeesSelect<true>;
|
||||
testimony: TestimonySelect<false> | TestimonySelect<true>;
|
||||
page: PageSelect<false> | PageSelect<true>;
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
media: MediaSelect<false> | MediaSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: null;
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
jobs?: {
|
||||
tasks: unknown;
|
||||
workflows?: unknown;
|
||||
};
|
||||
}
|
||||
export interface UserAuthOperations {
|
||||
forgotPassword: {
|
||||
|
|
@ -64,10 +89,17 @@ export interface Parish {
|
|||
slug: string;
|
||||
churches: (string | Church)[];
|
||||
employees?: (string | Employee)[] | null;
|
||||
contact: string;
|
||||
title: string;
|
||||
contactPersons?:
|
||||
| {
|
||||
title: string;
|
||||
description: string;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
description: string;
|
||||
photo?: (string | null) | Media;
|
||||
history: string;
|
||||
contact: string;
|
||||
photo: string | Media;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
|
@ -124,8 +156,10 @@ export interface Worship {
|
|||
date: string;
|
||||
location: string | Church;
|
||||
type: 'MASS' | 'FAMILY' | 'WORD';
|
||||
cancelled: boolean;
|
||||
title?: string | null;
|
||||
cancelled: boolean;
|
||||
liturgicalDay?: string | null;
|
||||
celebrant?: string | null;
|
||||
description?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
|
|
@ -150,22 +184,23 @@ export interface Blog {
|
|||
photo?: (string | null) | Media;
|
||||
title: string;
|
||||
parish?: (string | Parish)[] | null;
|
||||
isHighlight: boolean;
|
||||
text: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
content?:
|
||||
| (
|
||||
| {
|
||||
quoteText: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'Quote';
|
||||
}
|
||||
| {
|
||||
sliderContent: string;
|
||||
content: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'ContentWithSlider';
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
|
@ -188,7 +223,8 @@ export interface Event {
|
|||
id: string;
|
||||
photo?: (string | null) | Media;
|
||||
title: string;
|
||||
datum: string;
|
||||
date: string;
|
||||
location: string;
|
||||
parish?: (string | Parish)[] | null;
|
||||
group?: (string | null) | Group;
|
||||
shortDescription: string;
|
||||
|
|
@ -301,6 +337,73 @@ export interface User {
|
|||
lockUntil?: string | null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'parish';
|
||||
value: string | Parish;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'church';
|
||||
value: string | Church;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'worship';
|
||||
value: string | Worship;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'vermeldungen';
|
||||
value: string | Vermeldungen;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'blog';
|
||||
value: string | Blog;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'tweet';
|
||||
value: string | Tweet;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'event';
|
||||
value: string | Event;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'group';
|
||||
value: string | Group;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'employees';
|
||||
value: string | Employee;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'testimony';
|
||||
value: string | Testimony;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'page';
|
||||
value: string | Page;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'media';
|
||||
value: string | Media;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
|
|
@ -335,6 +438,261 @@ export interface PayloadMigration {
|
|||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "parish_select".
|
||||
*/
|
||||
export interface ParishSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
slug?: T;
|
||||
churches?: T;
|
||||
employees?: T;
|
||||
contactPersons?:
|
||||
| T
|
||||
| {
|
||||
title?: T;
|
||||
description?: T;
|
||||
id?: T;
|
||||
};
|
||||
description?: T;
|
||||
history?: T;
|
||||
contact?: T;
|
||||
photo?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "church_select".
|
||||
*/
|
||||
export interface ChurchSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
address?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "worship_select".
|
||||
*/
|
||||
export interface WorshipSelect<T extends boolean = true> {
|
||||
date?: T;
|
||||
location?: T;
|
||||
type?: T;
|
||||
title?: T;
|
||||
cancelled?: T;
|
||||
liturgicalDay?: T;
|
||||
celebrant?: T;
|
||||
description?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "vermeldungen_select".
|
||||
*/
|
||||
export interface VermeldungenSelect<T extends boolean = true> {
|
||||
date?: T;
|
||||
parish?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "blog_select".
|
||||
*/
|
||||
export interface BlogSelect<T extends boolean = true> {
|
||||
photo?: T;
|
||||
title?: T;
|
||||
parish?: T;
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
Quote?:
|
||||
| T
|
||||
| {
|
||||
quoteText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
ContentWithSlider?:
|
||||
| T
|
||||
| {
|
||||
sliderContent?: T;
|
||||
content?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "tweet_select".
|
||||
*/
|
||||
export interface TweetSelect<T extends boolean = true> {
|
||||
parish?: T;
|
||||
text?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "event_select".
|
||||
*/
|
||||
export interface EventSelect<T extends boolean = true> {
|
||||
photo?: T;
|
||||
title?: T;
|
||||
date?: T;
|
||||
location?: T;
|
||||
parish?: T;
|
||||
group?: T;
|
||||
shortDescription?: T;
|
||||
description?: T;
|
||||
cancelled?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "group_select".
|
||||
*/
|
||||
export interface GroupSelect<T extends boolean = true> {
|
||||
photo?: T;
|
||||
name?: T;
|
||||
description?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "employees_select".
|
||||
*/
|
||||
export interface EmployeesSelect<T extends boolean = true> {
|
||||
photo?: T;
|
||||
name?: T;
|
||||
occupation?: T;
|
||||
email?: T;
|
||||
telephone?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "testimony_select".
|
||||
*/
|
||||
export interface TestimonySelect<T extends boolean = true> {
|
||||
testimony?: T;
|
||||
name?: T;
|
||||
occupation?: T;
|
||||
category?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "page_select".
|
||||
*/
|
||||
export interface PageSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
slug?: T;
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
content?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
title?:
|
||||
| T
|
||||
| {
|
||||
title?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
testimony?:
|
||||
| T
|
||||
| {
|
||||
testimony?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
roles?: T;
|
||||
groups?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
resetPasswordToken?: T;
|
||||
resetPasswordExpiration?: T;
|
||||
salt?: T;
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "media_select".
|
||||
*/
|
||||
export interface MediaSelect<T extends boolean = true> {
|
||||
alt?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
url?: T;
|
||||
thumbnailURL?: T;
|
||||
filename?: T;
|
||||
mimeType?: T;
|
||||
filesize?: T;
|
||||
width?: T;
|
||||
height?: T;
|
||||
focalX?: T;
|
||||
focalY?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
*/
|
||||
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||
document?: T;
|
||||
globalSlug?: T;
|
||||
user?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences_select".
|
||||
*/
|
||||
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
key?: T;
|
||||
value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations_select".
|
||||
*/
|
||||
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
batch?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
|
|
|
|||
28
src/utils/church.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Convert string to a church
|
||||
* @param s
|
||||
*/
|
||||
export const church = (s: string) : "anna" | "christophorus" | "richard" | "eduard" | "clara" => {
|
||||
|
||||
if (s.toLowerCase().includes("anna")) {
|
||||
return "anna"
|
||||
}
|
||||
|
||||
if (s.toLowerCase().includes("christophorus")) {
|
||||
return "christophorus"
|
||||
}
|
||||
|
||||
if (s.toLowerCase().includes("richard")) {
|
||||
return "richard"
|
||||
}
|
||||
|
||||
if (s.toLowerCase().includes("eduard")) {
|
||||
return "eduard"
|
||||
}
|
||||
|
||||
if (s.toLowerCase().includes("clara")) {
|
||||
return "clara"
|
||||
}
|
||||
|
||||
return "clara";
|
||||
}
|
||||
13
src/utils/dto/blog.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Blog } from '@/payload-types'
|
||||
import { Slide } from '@/compositions/ImageCardSlider/ImageCardSlider'
|
||||
|
||||
export const blogToSlides = (blog: Blog[]): Slide[] => {
|
||||
return blog.map(b => {
|
||||
return {
|
||||
id: b.id,
|
||||
title: b.title,
|
||||
href: `/blog/${b.id}`,
|
||||
src: typeof b.photo === "string" ? b.photo : b.photo?.url || ""
|
||||
}
|
||||
})
|
||||
}
|
||||
15
src/utils/dto/events.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { Event } from '@/payload-types'
|
||||
import { EventRowProps } from '@/components/EventRow/EventRow'
|
||||
|
||||
export const transformEvents = (events: Event[]): EventRowProps[] => {
|
||||
return events.map(e => {
|
||||
return {
|
||||
id: e.id,
|
||||
title: e.title,
|
||||
date: e.date,
|
||||
href: `/veranstaltungen/${e.id}`,
|
||||
location: e.location,
|
||||
cancelled: e.cancelled,
|
||||
}
|
||||
})
|
||||
}
|
||||
32
src/utils/dto/worship.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { Worship } from '@/payload-types'
|
||||
import { EventRowProps } from '@/components/EventRow/EventRow'
|
||||
|
||||
/**
|
||||
* Transform the worship category to a readable string
|
||||
*/
|
||||
export const transformCategory = (category: "MASS" | "FAMILY" | "WORD"): string => {
|
||||
const type = {
|
||||
'MASS': 'Eucharistiefeier',
|
||||
'FAMILY': 'Familienmesse',
|
||||
'WORD': 'Wort-Gottes-Feier',
|
||||
}
|
||||
|
||||
return type[category]
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform worship data to `EventRow` component properties
|
||||
*/
|
||||
export const tranformWorship = (worship: Worship[]): EventRowProps[] => {
|
||||
|
||||
return worship.map(w => {
|
||||
return {
|
||||
id: w.id,
|
||||
title: transformCategory(w.type),
|
||||
date: w.date,
|
||||
href: `/gottesdienst/${w.id}`,
|
||||
location: typeof w.location === 'string' ? w.location : w.location.name,
|
||||
cancelled: w.cancelled,
|
||||
}
|
||||
})
|
||||
}
|
||||