feature: group page
This commit is contained in:
parent
388ab0b2e6
commit
9ac5c43e65
10 changed files with 303 additions and 74 deletions
|
|
@ -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
|
|||
</Container>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
{data.content.map(item => {
|
||||
if (item.blockType === "text" && item.content_html) {
|
||||
return (
|
||||
<Container key={item.id}>
|
||||
<HTMLText width={item.width} html={item.content_html} />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
<Blocks content={data.content} />
|
||||
|
||||
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>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -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
|
|||
<ImageWithText
|
||||
title={name}
|
||||
backgroundColor={"soft"}
|
||||
text={description}
|
||||
text={shortDescription}
|
||||
image={media}
|
||||
schema={"contrast"}
|
||||
/>
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +52,7 @@ export default async function GroupPage({ params }: { params: Promise<{slug: str
|
|||
<Container>
|
||||
<Title title={name} />
|
||||
<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} />
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
5
src/app/gruppe/[slug]/styles.module.scss
Normal file
5
src/app/gruppe/[slug]/styles.module.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
@import "template.scss";
|
||||
|
||||
.content h3, .content h4, .content h5, .content h6 {
|
||||
color: $base-color;
|
||||
}
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
14
src/components/RawHTML/styles.module.scss
Normal file
14
src/components/RawHTML/styles.module.scss
Normal file
|
|
@ -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;
|
||||
}
|
||||
68
src/compositions/Blocks/Blocks.tsx
Normal file
68
src/compositions/Blocks/Blocks.tsx
Normal file
|
|
@ -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>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue