Files
bmp-website-2026/src/collections/Pages/index.ts
2026-06-22 11:44:35 +02:00

341 lines
11 KiB
TypeScript

import type { CollectionConfig } from 'payload'
import { authenticated } from '../../access/authenticated'
import { authenticatedOrPublished } from '../../access/authenticatedOrPublished'
import { Archive } from '../../blocks/ArchiveBlock/config'
import { CallToAction } from '../../blocks/CallToAction/config'
import { Content } from '../../blocks/Content/config'
import { FormBlock } from '../../blocks/Form/config'
import { MediaBlock } from '../../blocks/MediaBlock/config'
import { hero } from '@/heros/config'
import { aboutFields } from './aboutFields'
import { contactFields } from './contactFields'
import { datenschutzFields } from './datenschutzFields'
import { formularUploadFields } from './formularUploadFields'
import { homeFields } from './homeFields'
import { impressumFields } from './impressumFields'
import { mitgliedWerdenFields } from './mitgliedWerdenFields'
import { netzwerkFields } from './netzwerkFields'
import { participationFields } from './participationFields'
import { preistraegerIndexFields } from './preistraegerIndexFields'
import { pressIndexFields } from './pressIndexFields'
import { slugField } from 'payload'
import { populatePublishedAt } from '../../hooks/populatePublishedAt'
import { generatePreviewPath } from '../../utilities/generatePreviewPath'
import { revalidateDelete, revalidatePage } from './hooks/revalidatePage'
import {
MetaDescriptionField,
MetaImageField,
MetaTitleField,
OverviewField,
PreviewField,
} from '@payloadcms/plugin-seo/fields'
const isHomePage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/' || slug === 'startseite' || slug === 'home' || title === 'home' || title === 'startseite'
}
const isContactPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/kontakt' || slug === 'kontakt' || slug === 'contact' || title === 'kontakt' || title === 'contact'
}
const isParticipationPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/teilnahme' || slug === 'teilnahme' || slug === 'participation' || title === 'teilnahme' || title === 'participation'
}
const isAboutPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/der-bmp' || slug === 'der-bmp' || slug === 'about' || title === 'der bmp' || title === 'about'
}
const isImpressumPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/impressum' || slug === 'impressum' || title === 'impressum'
}
const isDatenschutzPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/datenschutz' || slug === 'datenschutz' || title === 'datenschutz'
}
const isPreistraegerIndexPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/preistraeger' || slug === 'preistraeger' || title === 'preisträger' || title === 'preistraeger'
}
const isPressIndexPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/presse' || slug === 'presse' || slug === 'press' || title === 'presse' || title === 'press'
}
const isFormularUploadPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/formular-hochladen' || slug === 'formular-hochladen' || slug === 'upload' || title === 'formular hochladen'
}
const isNetzwerkPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/netzwerk' || slug === 'netzwerk' || slug === 'network' || title === 'netzwerk' || title === 'network'
}
const isMitgliedWerdenPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) => {
const slug = siblingData?.slug
const spaPath = siblingData?.spaPath
const title = siblingData?.title?.toLowerCase()
return spaPath === '/mitglied-werden' || slug === 'mitglied-werden' || slug === 'membership' || title === 'mitglied werden'
}
const isManagedSpaPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) =>
isHomePage(undefined, siblingData) ||
isContactPage(undefined, siblingData) ||
isParticipationPage(undefined, siblingData) ||
isAboutPage(undefined, siblingData) ||
isImpressumPage(undefined, siblingData) ||
isDatenschutzPage(undefined, siblingData) ||
isPreistraegerIndexPage(undefined, siblingData) ||
isPressIndexPage(undefined, siblingData) ||
isFormularUploadPage(undefined, siblingData) ||
isNetzwerkPage(undefined, siblingData) ||
isMitgliedWerdenPage(undefined, siblingData)
export const Pages: CollectionConfig<'pages'> = {
slug: 'pages',
access: {
create: authenticated,
delete: authenticated,
read: authenticatedOrPublished,
update: authenticated,
},
// This config controls what's populated by default when a page is referenced
// https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property
// Type safe if the collection slug generic is passed to `CollectionConfig` - `CollectionConfig<'pages'>
defaultPopulate: {
title: true,
slug: true,
},
admin: {
defaultColumns: ['title', 'spaPath', 'slug', 'updatedAt'],
livePreview: {
url: ({ data, req }) =>
generatePreviewPath({
slug: data?.spaPath || data?.slug,
collection: 'pages',
req,
}),
},
preview: (data, { req }) =>
generatePreviewPath({
slug: ((data?.spaPath as string | undefined) || (data?.slug as string)),
collection: 'pages',
req,
}),
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
type: 'tabs',
tabs: [
{
admin: {
condition: (data) => !isManagedSpaPage(undefined, data),
},
fields: [hero],
label: 'Hero',
},
{
admin: {
condition: (data) => !isManagedSpaPage(undefined, data),
},
fields: [
{
name: 'layout',
type: 'blocks',
blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock],
required: true,
admin: {
initCollapsed: true,
},
},
],
label: 'Content',
},
{
admin: {
condition: (data) => isHomePage(undefined, data),
},
fields: homeFields,
label: 'Home Page',
},
{
admin: {
condition: (data) => isContactPage(undefined, data),
},
fields: contactFields,
label: 'Contact Page',
},
{
admin: {
condition: (data) => isParticipationPage(undefined, data),
},
fields: participationFields,
label: 'Participation Page',
},
{
admin: {
condition: (data) => isAboutPage(undefined, data),
},
fields: aboutFields,
label: 'About Page',
},
{
admin: {
condition: (data) => isImpressumPage(undefined, data),
},
fields: impressumFields,
label: 'Impressum Page',
},
{
admin: {
condition: (data) => isDatenschutzPage(undefined, data),
},
fields: datenschutzFields,
label: 'Datenschutz Page',
},
{
admin: {
condition: (data) => isPreistraegerIndexPage(undefined, data),
},
fields: preistraegerIndexFields,
label: 'Preisträger Index Page',
},
{
admin: {
condition: (data) => isPressIndexPage(undefined, data),
},
fields: pressIndexFields,
label: 'Press Index Page',
},
{
admin: {
condition: (data) => isFormularUploadPage(undefined, data),
},
fields: formularUploadFields,
label: 'Formular Upload Page',
},
{
admin: {
condition: (data) => isNetzwerkPage(undefined, data),
},
fields: netzwerkFields,
label: 'Network Page',
},
{
admin: {
condition: (data) => isMitgliedWerdenPage(undefined, data),
},
fields: mitgliedWerdenFields,
label: 'Membership Page',
},
{
name: 'meta',
label: 'SEO',
fields: [
OverviewField({
titlePath: 'meta.title',
descriptionPath: 'meta.description',
imagePath: 'meta.image',
}),
MetaTitleField({
hasGenerateFn: true,
}),
MetaImageField({
relationTo: 'media',
}),
MetaDescriptionField({}),
PreviewField({
// if the `generateUrl` function is configured
hasGenerateFn: true,
// field paths to match the target field for data
titlePath: 'meta.title',
descriptionPath: 'meta.description',
}),
],
},
],
},
{
name: 'publishedAt',
type: 'date',
admin: {
position: 'sidebar',
},
},
{
name: 'spaPath',
type: 'text',
index: true,
admin: {
description: 'Route in the legacy SPA used for previewing the current migrated page state.',
position: 'sidebar',
},
},
slugField(),
],
hooks: {
afterChange: [revalidatePage],
beforeChange: [populatePublishedAt],
afterDelete: [revalidateDelete],
},
versions: {
drafts: {
autosave: {
interval: 100, // We set this interval for optimal live preview
},
schedulePublish: true,
},
maxPerDoc: 50,
},
}