diff --git a/src/app/blog/[id]/page.tsx b/src/app/blog/[id]/page.tsx index f691567..511c75e 100644 --- a/src/app/blog/[id]/page.tsx +++ b/src/app/blog/[id]/page.tsx @@ -13,6 +13,7 @@ import { Button } from '@/components/Button/Button' import { ContactSection } from '@/compositions/ContactSection/ContactSection' import { Gallery } from '@/components/Gallery/Gallery' import { transformGallery } from '@/utils/dto/gallery' +import { Blocks } from '@/compositions/Blocks/Blocks' async function fetchBlog(id: string) { const res = await fetch(`http://localhost:3000/api/blog/${id}`) @@ -54,50 +55,8 @@ export default async function BlogPage({ params }: { params: Promise<{id: string -
- {data.content.map(item => { - if (item.blockType === "text" && item.content_html) { - return ( - - - - ); - } + - if (item.blockType === "document" && typeof item.file === "object") { - return ( - -
- -
-
- ) - } - - if (item.blockType === "contactform") { - return ( - - ) - } - - if (item.blockType === "gallery") { - return ( -
- -
- ) - } - })} -
- - { shouldAddMargin && -
- } ) } \ No newline at end of file diff --git a/src/app/gruppe/[slug]/page.tsx b/src/app/gruppe/[slug]/page.tsx index 4f3acf8..860a6c3 100644 --- a/src/app/gruppe/[slug]/page.tsx +++ b/src/app/gruppe/[slug]/page.tsx @@ -1,3 +1,4 @@ +import styles from "./styles.module.scss" import { ImageWithText } from '@/compositions/ImageWithText/ImageWithText' import { fetchGroup } from '@/fetch/group' import { notFound } from 'next/navigation' @@ -9,6 +10,10 @@ import { transformEvents } from '@/utils/dto/events' import { Container } from '@/components/Container/Container' import { HR } from '@/components/HorizontalRule/HorizontalRule' import { TextDiv } from '@/components/Text/TextDiv' +import { Col } from '@/components/Flex/Col' +import { Row } from '@/components/Flex/Row' +import { RawHTML } from '@/components/RawHTML/RawHTML' +import { Blocks } from '@/compositions/Blocks/Blocks' export default async function GroupPage({ params }: { params: Promise<{slug: string}>}) { @@ -19,7 +24,7 @@ export default async function GroupPage({ params }: { params: Promise<{slug: str notFound(); } - const {id, description, photo,name } = groups.docs[0] + const {id, shortDescription, photo,name, text_html, content } = groups.docs[0] const media = { src: typeof photo === "object" && photo ? photo.url || "" : "", width: typeof photo === "object" && photo ? photo.width || 0 : 0, @@ -35,8 +40,9 @@ export default async function GroupPage({ params }: { params: Promise<{slug: str } @@ -46,7 +52,7 @@ export default async function GroupPage({ params }: { params: Promise<{slug: str <strong> - <TextDiv text={description} /> + <TextDiv text={shortDescription} /> </strong> </Container> @@ -56,16 +62,39 @@ export default async function GroupPage({ params }: { params: Promise<{slug: str } - { events && events.docs.length > 0 && <Section> <Container> - <Title title={"Veranstaltungen"} size={"md"} /> - <Events events={transformEvents(events.docs)} n={3} /> + <Row> + <Col> + <div className={styles.content}> + { text_html && + <RawHTML html={text_html} /> + } + </div> + </Col> + <Col> + { events && events.docs.length > 0 && + <> + <Title + title={"Veranstaltungen"} + size={"md"} + color={"contrast"} + /> + <Events + events={transformEvents(events.docs)} + n={3} + schema={"contrast"} + /> + </> + } + </Col> + </Row> </Container> - <Section></Section> </Section> - } + { content && content.length > 0 && + <Blocks content={content} /> + } </> ) } \ No newline at end of file diff --git a/src/app/gruppe/[slug]/styles.module.scss b/src/app/gruppe/[slug]/styles.module.scss new file mode 100644 index 0000000..b542a8a --- /dev/null +++ b/src/app/gruppe/[slug]/styles.module.scss @@ -0,0 +1,5 @@ +@import "template.scss"; + +.content h3, .content h4, .content h5, .content h6 { + color: $base-color; +} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 5a1d289..9e1b9d7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -57,23 +57,23 @@ export default function RootLayout({ items: [ { title: "Kathoccino", - description: "Begegnung mit Gott", + description: "Brunchgruppe für Jungerwachsene", href: "/gruppe/kathocchino" }, { title: "Credo & Agape", - description: "Gebet der Meditation", - href: "https://" + description: "Gesprächskreis für Erwachsene ab 45 Jahren", + href: "/gruppe/credo-agape" }, { title: "Mädchengruppe", - description: "Stille Begegnung mit Gott", - href: "https://" + description: "Zusammen die Welt entdecken", + href: "/gruppe/maedchen" }, { title: "Alphakurs", - description: "Dank, Ehre und Freude", - href: "https://" + description: "Freude am glauben entdecken", + href: "/gruppe/alphakurs" }, ] }, @@ -81,14 +81,14 @@ export default function RootLayout({ title: "Musik", items: [ { - title: "Little Richards", - description: "Der Hausband von St. Richard", - href: "https://" + title: "Chor St. Clara", + description: "Singen und mitgestalten", + href: "/gruppe/chor-st-clara" }, { title: "Kindergruppe", description: "Jeden Freitag singen und spielen", - href: "https://" + href: "/gruppe/kinder-musik" } ] } @@ -154,12 +154,12 @@ export default function RootLayout({ { title: "Anbetung", description: "Stille Begegnung mit Gott", - href: "https://" + href: "/gruppe/eucharistische-anbetung" }, { - title: "Lobpreis", + title: "Holy Hour", description: "Dank, Ehre und Freude", - href: "https://" + href: "/gruppe/lobpreis" }, ] } @@ -178,12 +178,12 @@ export default function RootLayout({ title: "Ehrenamt", items: [ { - href: 'http://', + href: '/gruppe/waermestube', title: 'Wärmestube', description: 'Kälteschutz für Bedurftigen', }, { - href: 'http://', + href: '/gruppe/essen-ist-fertig', title: 'Essen ist Fertig', description: 'Essensausgabe Neukölln', }, @@ -195,7 +195,22 @@ export default function RootLayout({ ] }, { - title: "Aktivitaten", + title: "Projekte", + items: [ + { + title: "Umgekehrter Advent", + description: "Geben statt nehmen ", + href: "/gruppe/umgekehrter-advent" + }, + { + title: "Dicke Linda", + description: "Marktstand auf dem Kranoldplatz", + href: "/gruppe/dicke-linda" + }, + ] + }, + { + title: "Aktivitäten", items: [ { title: "Kochen", diff --git a/src/collections/Groups.ts b/src/collections/Groups.ts index 896a8a9..74772cb 100644 --- a/src/collections/Groups.ts +++ b/src/collections/Groups.ts @@ -1,5 +1,10 @@ import { CollectionConfig } from 'payload' import { isAdminOrEmployee } from '@/collections/access/admin' +import { ParagraphBlock } from '@/collections/blocks/Paragraph' +import { GalleryBlock } from '@/collections/blocks/Gallery' +import { ContactformBlock } from '@/collections/blocks/Contactform' +import { DocumentBlock } from '@/collections/blocks/Document' +import { lexicalHTML } from '@payloadcms/richtext-lexical' export const Groups: CollectionConfig = { slug: 'group', @@ -38,13 +43,32 @@ export const Groups: CollectionConfig = { unique: true }, { - name: 'description', + name: 'shortDescription', type: 'textarea', label: { - de: 'Umschreibung', + de: 'Kurzumschreibung', }, required: true, }, + { + name: 'text', + type: 'richText', + label: { + de: 'Umschreibung', + }, + required: false, + }, + lexicalHTML('text', { name: 'text_html' }), + { + name: 'content', + type: 'blocks', + blocks: [ + ParagraphBlock, + GalleryBlock, + DocumentBlock, + ContactformBlock + ] + } ], admin: { useAsTitle: 'name', diff --git a/src/components/RawHTML/RawHTML.tsx b/src/components/RawHTML/RawHTML.tsx index b7f4fde..ac8bca1 100644 --- a/src/components/RawHTML/RawHTML.tsx +++ b/src/components/RawHTML/RawHTML.tsx @@ -1,9 +1,14 @@ +import styles from "./styles.module.scss" + type RawHTMLProps = { html: string } export const RawHTML = ({html}: RawHTMLProps) => { return ( - <div dangerouslySetInnerHTML={{__html: html}}></div> + <div + className={styles.content} + dangerouslySetInnerHTML={{__html: html}} + ></div> ) } \ No newline at end of file diff --git a/src/components/RawHTML/styles.module.scss b/src/components/RawHTML/styles.module.scss new file mode 100644 index 0000000..ec0ddcf --- /dev/null +++ b/src/components/RawHTML/styles.module.scss @@ -0,0 +1,14 @@ +@import "template.scss"; + +.content a { + color: inherit; +} + +.content a:hover { + color: $base-color; +} + +.content h3 { + font-size: 33px; + margin: 33px 0 20px 0; +} \ No newline at end of file diff --git a/src/compositions/Blocks/Blocks.tsx b/src/compositions/Blocks/Blocks.tsx new file mode 100644 index 0000000..1148023 --- /dev/null +++ b/src/compositions/Blocks/Blocks.tsx @@ -0,0 +1,68 @@ +import { Blog } from "@/payload-types" +import { Container } from '@/components/Container/Container' +import { HTMLText } from '@/components/Text/HTMLText' +import { Section } from '@/components/Section/Section' +import { Button } from '@/components/Button/Button' +import { ContactSection } from '@/compositions/ContactSection/ContactSection' +import { Gallery } from '@/components/Gallery/Gallery' +import { transformGallery } from '@/utils/dto/gallery' + +type BlocksProps = { + content: Blog['content'] +} + +export function Blocks({ content }: BlocksProps) { + + // determine if some margin at the bottom should be added + const length = content.length; + const shouldAddMargin = content[length - 1].blockType === "text" + + return ( + <> + <div> + {content.map(item => { + if (item.blockType === "text" && item.content_html) { + return ( + <Container key={item.id}> + <HTMLText width={item.width} html={item.content_html} /> + </Container> + ); + } + + if (item.blockType === "document" && typeof item.file === "object") { + return ( + <Container key={item.id}> + <Section padding={"medium"}> + <Button size={"lg"} href={item.file.url || "notfound"} schema={"contrast"}>{item.button}</Button> + </Section> + </Container> + ) + } + + if (item.blockType === "contactform") { + return ( + <ContactSection + key={item.id} + title={item.title} + description={item.description} + backgroundColor={"off-white"} + /> + ) + } + + if (item.blockType === "gallery") { + return ( + <Section key={item.id}> + <Gallery items={transformGallery(item.items)} /> + </Section> + ) + } + })} + </div> + + { shouldAddMargin && + <Section></Section> + } + </> + ) +} \ No newline at end of file diff --git a/src/payload-types.ts b/src/payload-types.ts index e281214..3ac9bf3 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -376,7 +376,73 @@ export interface Group { photo?: (string | null) | Media; name: string; slug: string; - description: string; + shortDescription: string; + 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; + } | null; + text_html?: string | null; + content?: + | ( + | { + content: { + 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_html?: string | null; + width: '1/2' | '3/4'; + id?: string | null; + blockName?: string | null; + blockType: 'text'; + } + | { + items: { + photo: string | Media; + id?: string | null; + }[]; + id?: string | null; + blockName?: string | null; + blockType: 'gallery'; + } + | { + file: string | Document; + button: string; + id?: string | null; + blockName?: string | null; + blockType: 'document'; + } + | { + title: string; + description: string; + email: string; + id?: string | null; + blockName?: string | null; + blockType: 'contactform'; + } + )[] + | null; updatedAt: string; createdAt: string; } @@ -768,7 +834,51 @@ export interface GroupSelect<T extends boolean = true> { photo?: T; name?: T; slug?: T; - description?: T; + shortDescription?: T; + text?: T; + text_html?: T; + content?: + | T + | { + text?: + | T + | { + content?: T; + content_html?: T; + width?: T; + id?: T; + blockName?: T; + }; + gallery?: + | T + | { + items?: + | T + | { + photo?: T; + id?: T; + }; + id?: T; + blockName?: T; + }; + document?: + | T + | { + file?: T; + button?: T; + id?: T; + blockName?: T; + }; + contactform?: + | T + | { + title?: T; + description?: T; + email?: T; + id?: T; + blockName?: T; + }; + }; updatedAt?: T; createdAt?: T; } diff --git a/src/utils/dto/highlight.ts b/src/utils/dto/highlight.ts index 7cd2914..7858f8e 100644 --- a/src/utils/dto/highlight.ts +++ b/src/utils/dto/highlight.ts @@ -14,7 +14,7 @@ export const highlightLink = (highlight: Highlight) => { case 'worship': return `/gottesdienst/${highlight.link.value.id}`; case 'event': - return `/event/${highlight.link.value.id}`; + return `/veranstaltungen/${highlight.link.value.id}`; case 'blog': return `/blog/${highlight.link.value.id}`; default: