feature: blog page
This commit is contained in:
parent
46b46c77c9
commit
2f999ed437
14 changed files with 7341 additions and 163 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { Section } from '../../../../components/Section/Section'
|
||||
import { Container } from '../../../../components/Container/Container'
|
||||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { Title } from '@/components/Title/Title'
|
||||
import { TextDiv } from '@/components/Text/TextDiv'
|
||||
import { Blog } from '@/payload-types'
|
||||
|
|
@ -30,15 +30,15 @@ export default async function BlogPage({ params }: { params: Promise<{id: string
|
|||
}
|
||||
|
||||
// determine if some margin at the bottom should be added
|
||||
const length = data.content.length;
|
||||
const shouldAddMargin = data.content[length - 1].blockType === "text"
|
||||
const length = data.content.content.length;
|
||||
const shouldAddMargin = data.content.content[length - 1].blockType === "text"
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section paddingBottom={"small"}>
|
||||
<Container>
|
||||
<Title title={data.title} color={"contrast"}></Title>
|
||||
<TextDiv text={data.excerpt} />
|
||||
<TextDiv text={data.content.excerpt} />
|
||||
<p className={styles.published}>
|
||||
Publiziert am {readableDateTime(data.createdAt)}
|
||||
</p>
|
||||
|
|
@ -53,7 +53,7 @@ export default async function BlogPage({ params }: { params: Promise<{id: string
|
|||
</Container>
|
||||
</Section>
|
||||
|
||||
<Blocks content={data.content} />
|
||||
<Blocks content={data.content.content} />
|
||||
|
||||
<AdminMenu
|
||||
collection={"worship"}
|
||||
|
|
|
|||
36
src/app/(home)/blog/page.tsx
Normal file
36
src/app/(home)/blog/page.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { PageHeader } from '@/compositions/PageHeader/PageHeader'
|
||||
import { fetchBlogPosts } from '@/fetch/blog'
|
||||
import { BlogExcerpt } from '@/components/BlogExcerpt/BlogExcerpt'
|
||||
import { Section } from '@/components/Section/Section'
|
||||
import { Container } from '@/components/Container/Container'
|
||||
import { getPhoto } from '@/utils/dto/gallery'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
export default async function Page() {
|
||||
const blogs = await fetchBlogPosts(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
title={"Aktuelle Nachrichten"}
|
||||
description={"Im Blog der Katholischen Pfarrei Heilige Drei Könige finden Sie aktuelle Nachrichten und erfahren alles über das Gemeindeleben, kommende Veranstaltungen und besondere Gottesdienste."}
|
||||
/>
|
||||
|
||||
<Section padding={"small"}>
|
||||
<Container>
|
||||
{
|
||||
blogs?.docs.map(blog =>
|
||||
<BlogExcerpt
|
||||
key={blog.id}
|
||||
id={blog.id}
|
||||
title={blog.title}
|
||||
excerpt={blog.content.excerpt}
|
||||
photo={getPhoto('thumbnail', blog.photo)}
|
||||
/>)
|
||||
}
|
||||
</Container>
|
||||
</Section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { fetchEvents } from '@/fetch/events'
|
||||
import { fetchWorship } from '@/fetch/worship'
|
||||
import { fetchBlog } from '@/fetch/blog'
|
||||
import { fetchBlogPosts } from '@/fetch/blog'
|
||||
import { fetchHighlights } from '@/fetch/highlights'
|
||||
import { Home } from '@/pageComponents/Home/Home'
|
||||
import moment from 'moment'
|
||||
|
|
@ -16,7 +16,7 @@ export default async function HomePage() {
|
|||
fromDate: fromDate.toDate(),
|
||||
tillDate: tillDate.toDate(),
|
||||
});
|
||||
const blog = await fetchBlog()
|
||||
const blog = await fetchBlogPosts(true)
|
||||
const highlights = await fetchHighlights()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,16 +12,19 @@ export const Blog: CollectionConfig = {
|
|||
slug: 'blog',
|
||||
labels: {
|
||||
singular: {
|
||||
de: 'Blogpost'
|
||||
de: 'Blogpost',
|
||||
},
|
||||
plural: {
|
||||
de: 'Blog'
|
||||
}
|
||||
de: 'Blog',
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'photo',
|
||||
type: 'upload',
|
||||
label: {
|
||||
de: 'Bild'
|
||||
},
|
||||
relationTo: 'media',
|
||||
},
|
||||
{
|
||||
|
|
@ -29,50 +32,94 @@ export const Blog: CollectionConfig = {
|
|||
type: 'text',
|
||||
required: true,
|
||||
label: {
|
||||
de: "Titel"
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'parish',
|
||||
type: 'relationship',
|
||||
relationTo: 'parish',
|
||||
hasMany: true,
|
||||
label: {
|
||||
de: "Gemeinde"
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'excerpt',
|
||||
type: 'textarea',
|
||||
label: {
|
||||
de: 'Auszug'
|
||||
de: 'Titel',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'blocks',
|
||||
minRows: 1,
|
||||
maxRows: 20,
|
||||
blocks: [
|
||||
ParagraphBlock,
|
||||
DocumentBlock,
|
||||
DonationBlock,
|
||||
ContactformBlock,
|
||||
GalleryBlock,
|
||||
ButtonBlock
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
name: 'content',
|
||||
fields: [
|
||||
{
|
||||
name: 'excerpt',
|
||||
type: 'textarea',
|
||||
label: {
|
||||
de: 'Auszug',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'blocks',
|
||||
minRows: 1,
|
||||
maxRows: 20,
|
||||
blocks: [
|
||||
ParagraphBlock,
|
||||
DocumentBlock,
|
||||
DonationBlock,
|
||||
ContactformBlock,
|
||||
GalleryBlock,
|
||||
ButtonBlock,
|
||||
],
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'configuration',
|
||||
label: {
|
||||
de: 'Einstellungen'
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'showOnFrontpage',
|
||||
type: 'checkbox',
|
||||
label: {
|
||||
de: 'Anzeigen auf Startseite?',
|
||||
},
|
||||
defaultValue: true,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'displayFromDate',
|
||||
type: 'date',
|
||||
label: {
|
||||
de: 'Anzeigen von',
|
||||
},
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'displayTillDate',
|
||||
type: 'date',
|
||||
label: {
|
||||
de: 'Anzeigen bis',
|
||||
},
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'parish',
|
||||
type: 'relationship',
|
||||
relationTo: 'parish',
|
||||
hasMany: true,
|
||||
label: {
|
||||
de: 'Gemeinde',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
],
|
||||
required: true
|
||||
},
|
||||
],
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
hidden: hide
|
||||
hidden: hide,
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
create: isAdminOrEmployee(),
|
||||
update: isAdminOrEmployee(),
|
||||
delete: isAdminOrEmployee(),
|
||||
}
|
||||
},
|
||||
}
|
||||
17
src/components/BlogExcerpt/BlogExcerpt.stories.tsx
Normal file
17
src/components/BlogExcerpt/BlogExcerpt.stories.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { BlogExcerpt } from './BlogExcerpt'
|
||||
|
||||
const meta: Meta<typeof BlogExcerpt> = {
|
||||
component: BlogExcerpt,
|
||||
}
|
||||
|
||||
type Story = StoryObj<typeof BlogExcerpt>;
|
||||
export default meta
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
id: 'some_id',
|
||||
title: 'Some blog title',
|
||||
excerpt: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.'
|
||||
},
|
||||
}
|
||||
42
src/components/BlogExcerpt/BlogExcerpt.tsx
Normal file
42
src/components/BlogExcerpt/BlogExcerpt.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { Button } from '@/components/Button/Button'
|
||||
import Link from 'next/link'
|
||||
import styles from './styles.module.scss'
|
||||
import Image, { StaticImageData } from 'next/image'
|
||||
|
||||
type BlogExcerptProps = {
|
||||
id: string,
|
||||
title: string,
|
||||
excerpt: string
|
||||
photo: StaticImageData | undefined
|
||||
}
|
||||
|
||||
export const BlogExcerpt = ({id, title, excerpt, photo}: BlogExcerptProps) => {
|
||||
|
||||
const url = `/blog/${id}`;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div>
|
||||
{ photo &&
|
||||
<Link href={url}>
|
||||
<Image
|
||||
src={photo.src}
|
||||
width={photo.width}
|
||||
height={photo.height}
|
||||
alt={"Blogbild"}
|
||||
className={styles.image}
|
||||
/>
|
||||
</Link>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<h3><Link href={url} className={styles.title}>{title}</Link></h3>
|
||||
<p>{excerpt}</p>
|
||||
|
||||
<div className={styles.button}>
|
||||
<Button size={"md"} href={url}>Weiter lesen</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
22
src/components/BlogExcerpt/styles.module.scss
Normal file
22
src/components/BlogExcerpt/styles.module.scss
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.container {
|
||||
display: flex;
|
||||
gap: 50px;
|
||||
margin-bottom: 80px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.image {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ import { transformGallery } from '@/utils/dto/gallery'
|
|||
import { DonationForm } from '@/components/DonationForm/DonationForm'
|
||||
|
||||
type BlocksProps = {
|
||||
content: Blog['content']
|
||||
content: Blog['content']['content']
|
||||
}
|
||||
|
||||
export function Blocks({ content }: BlocksProps) {
|
||||
|
|
|
|||
|
|
@ -2,21 +2,72 @@ 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(
|
||||
/**
|
||||
* Fetches blog posts based on given criteria.
|
||||
*
|
||||
* @param {boolean} displayOnFrontpage - Indicates whether to display posts on the front page.
|
||||
* @returns {Promise<PaginatedDocs<Blog> | undefined>} - A Promise that resolves to the paginated list of blog posts, or undefined if an error occurs.
|
||||
*/
|
||||
export const fetchBlogPosts = async (displayOnFrontpage: boolean): Promise<PaginatedDocs<Blog> | undefined> => {
|
||||
const today = new Date();
|
||||
today.setHours(23, 59);
|
||||
|
||||
const query: any =
|
||||
{
|
||||
sort: "-date",
|
||||
select: {
|
||||
title: true,
|
||||
date: true,
|
||||
photo: true
|
||||
photo: true,
|
||||
"content": !displayOnFrontpage, // hack to fetch content only for the `/blog` page
|
||||
},
|
||||
where: {
|
||||
and: [
|
||||
{
|
||||
or: [
|
||||
{
|
||||
"configuration.displayFromDate": {
|
||||
equals: null
|
||||
}
|
||||
},
|
||||
{
|
||||
"configuration.displayFromDate": {
|
||||
less_than_equal: today.toISOString(),
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
or: [
|
||||
{
|
||||
"configuration.displayTillDate": {
|
||||
equals: null
|
||||
}
|
||||
},
|
||||
{
|
||||
"configuration.displayTillDate": {
|
||||
greater_than_equal: today.toISOString(),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
limit: 18
|
||||
},
|
||||
{ addQueryPrefix: true },
|
||||
)
|
||||
};
|
||||
|
||||
const resp = await fetch(`http://localhost:3000/api/blog`);
|
||||
if(displayOnFrontpage) {
|
||||
query.where.and.push({
|
||||
"configuration.showOnFrontpage": {
|
||||
equals: true
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const stringifiedQuery = stringify(query, {addQueryPrefix: true})
|
||||
|
||||
|
||||
const resp = await fetch(`http://localhost:3000/api/blog${stringifiedQuery}`);
|
||||
if (!resp.ok) return undefined;
|
||||
return resp.json();
|
||||
}
|
||||
6900
src/migrations/20250909_075603.json
Normal file
6900
src/migrations/20250909_075603.json
Normal file
File diff suppressed because it is too large
Load diff
24
src/migrations/20250909_075603.ts
Normal file
24
src/migrations/20250909_075603.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
ALTER TABLE "blog" RENAME COLUMN "excerpt" TO "content_excerpt";
|
||||
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2025-09-14T07:56:02.742Z';
|
||||
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2025-09-14T07:56:02.825Z';
|
||||
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2025-10-09T07:56:02.879Z';
|
||||
ALTER TABLE "blog" ADD COLUMN "configuration_show_on_frontpage" boolean DEFAULT true NOT NULL;
|
||||
ALTER TABLE "blog" ADD COLUMN "configuration_display_from_date" timestamp(3) with time zone;
|
||||
ALTER TABLE "blog" ADD COLUMN "configuration_display_till_date" timestamp(3) with time zone;`)
|
||||
}
|
||||
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2025-08-31T10:51:21.316Z';
|
||||
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2025-08-31T10:51:21.398Z';
|
||||
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2025-09-26T10:51:21.450Z';
|
||||
ALTER TABLE "blog" ADD COLUMN "excerpt" varchar NOT NULL;
|
||||
ALTER TABLE "blog" DROP COLUMN "content_excerpt";
|
||||
ALTER TABLE "blog" DROP COLUMN "configuration_show_on_frontpage";
|
||||
ALTER TABLE "blog" DROP COLUMN "configuration_display_from_date";
|
||||
ALTER TABLE "blog" DROP COLUMN "configuration_display_till_date";`)
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import * as migration_20250608_105124_new_blocks from './20250608_105124_new_blo
|
|||
import * as migration_20250818_143115_menu from './20250818_143115_menu';
|
||||
import * as migration_20250827_093559_magazine from './20250827_093559_magazine';
|
||||
import * as migration_20250827_105121_new_payload_version from './20250827_105121_new_payload_version';
|
||||
import * as migration_20250909_075603 from './20250909_075603';
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
|
|
@ -70,6 +71,11 @@ export const migrations = [
|
|||
{
|
||||
up: migration_20250827_105121_new_payload_version.up,
|
||||
down: migration_20250827_105121_new_payload_version.down,
|
||||
name: '20250827_105121_new_payload_version'
|
||||
name: '20250827_105121_new_payload_version',
|
||||
},
|
||||
{
|
||||
up: migration_20250909_075603.up,
|
||||
down: migration_20250909_075603.down,
|
||||
name: '20250909_075603'
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -67,24 +67,39 @@ export const Default: Story = {
|
|||
{
|
||||
id: 'b1',
|
||||
title: 'Blog 1',
|
||||
excerpt: '',
|
||||
content: [],
|
||||
content: {
|
||||
excerpt: '',
|
||||
content: []
|
||||
},
|
||||
configuration: {
|
||||
showOnFrontpage: false,
|
||||
},
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
{
|
||||
id: 'b2',
|
||||
title: 'Blog 2',
|
||||
excerpt: '',
|
||||
content: [],
|
||||
content: {
|
||||
excerpt: '',
|
||||
content: []
|
||||
},
|
||||
configuration: {
|
||||
showOnFrontpage: false,
|
||||
},
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
{
|
||||
id: 'b3',
|
||||
title: 'Blog 3',
|
||||
excerpt: '',
|
||||
content: [],
|
||||
content: {
|
||||
excerpt: '',
|
||||
content: []
|
||||
},
|
||||
configuration: {
|
||||
showOnFrontpage: false,
|
||||
},
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -327,68 +327,75 @@ export interface Blog {
|
|||
id: string;
|
||||
photo?: (string | null) | Media;
|
||||
title: string;
|
||||
parish?: (string | Parish)[] | null;
|
||||
excerpt: string;
|
||||
content: (
|
||||
| {
|
||||
content: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
content: {
|
||||
excerpt: string;
|
||||
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;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
content_html?: string | null;
|
||||
width: '1/2' | '3/4';
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'text';
|
||||
}
|
||||
| {
|
||||
file: string | Document;
|
||||
button: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'document';
|
||||
}
|
||||
| {
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'donation';
|
||||
}
|
||||
| {
|
||||
title: string;
|
||||
description: string;
|
||||
email: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'contactform';
|
||||
}
|
||||
| {
|
||||
items: {
|
||||
photo: string | Media;
|
||||
content_html?: string | null;
|
||||
width: '1/2' | '3/4';
|
||||
id?: string | null;
|
||||
}[];
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'gallery';
|
||||
}
|
||||
| {
|
||||
text: string;
|
||||
url: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'button';
|
||||
}
|
||||
)[];
|
||||
blockName?: string | null;
|
||||
blockType: 'text';
|
||||
}
|
||||
| {
|
||||
file: string | Document;
|
||||
button: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'document';
|
||||
}
|
||||
| {
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'donation';
|
||||
}
|
||||
| {
|
||||
title: string;
|
||||
description: string;
|
||||
email: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'contactform';
|
||||
}
|
||||
| {
|
||||
items: {
|
||||
photo: string | Media;
|
||||
id?: string | null;
|
||||
}[];
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'gallery';
|
||||
}
|
||||
| {
|
||||
text: string;
|
||||
url: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'button';
|
||||
}
|
||||
)[];
|
||||
};
|
||||
configuration: {
|
||||
showOnFrontpage: boolean;
|
||||
displayFromDate?: string | null;
|
||||
displayTillDate?: string | null;
|
||||
parish?: (string | Parish)[] | null;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
|
@ -841,64 +848,75 @@ export interface CalendarSelect<T extends boolean = true> {
|
|||
export interface BlogSelect<T extends boolean = true> {
|
||||
photo?: T;
|
||||
title?: T;
|
||||
parish?: T;
|
||||
excerpt?: T;
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
excerpt?: T;
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
content?: T;
|
||||
content_html?: T;
|
||||
width?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
document?:
|
||||
| T
|
||||
| {
|
||||
file?: T;
|
||||
button?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
donation?:
|
||||
| T
|
||||
| {
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
contactform?:
|
||||
| T
|
||||
| {
|
||||
title?: T;
|
||||
description?: T;
|
||||
email?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
gallery?:
|
||||
| T
|
||||
| {
|
||||
items?:
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
photo?: T;
|
||||
content?: T;
|
||||
content_html?: T;
|
||||
width?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
document?:
|
||||
| T
|
||||
| {
|
||||
file?: T;
|
||||
button?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
donation?:
|
||||
| T
|
||||
| {
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
contactform?:
|
||||
| T
|
||||
| {
|
||||
title?: T;
|
||||
description?: T;
|
||||
email?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
gallery?:
|
||||
| T
|
||||
| {
|
||||
items?:
|
||||
| T
|
||||
| {
|
||||
photo?: T;
|
||||
id?: T;
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
button?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
url?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
button?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
url?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
configuration?:
|
||||
| T
|
||||
| {
|
||||
showOnFrontpage?: T;
|
||||
displayFromDate?: T;
|
||||
displayTillDate?: T;
|
||||
parish?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue