feat: manage impressum page via payload
This commit is contained in:
81
src/collections/Pages/impressumFields.ts
Normal file
81
src/collections/Pages/impressumFields.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import type { Field } from 'payload'
|
||||
|
||||
import { impressumContent } from '@/spa/impressumContent'
|
||||
|
||||
const text = (name: string, label: string, defaultValue?: string): Field => ({
|
||||
name,
|
||||
type: 'text',
|
||||
label,
|
||||
defaultValue,
|
||||
})
|
||||
|
||||
const textarea = (name: string, label: string, defaultValue?: string): Field => ({
|
||||
name,
|
||||
type: 'textarea',
|
||||
label,
|
||||
defaultValue,
|
||||
})
|
||||
|
||||
const sectionAdmin = (description: string) => ({
|
||||
description,
|
||||
initCollapsed: true,
|
||||
})
|
||||
|
||||
export const impressumFields: Field[] = [
|
||||
{
|
||||
name: 'impressum',
|
||||
label: 'Impressum page content',
|
||||
type: 'group',
|
||||
admin: {
|
||||
description:
|
||||
'Edit the Impressum page content. Legal section body blocks are stored as JSON so nested paragraphs, lists, notices, addresses, and subsections can keep their frontend order.',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'hero',
|
||||
label: '01 · Hero',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Top legal page heading and description line.'),
|
||||
fields: [
|
||||
text('backLabel', 'Back link label', impressumContent.hero.backLabel),
|
||||
text('eyebrow', 'Eyebrow', impressumContent.hero.eyebrow),
|
||||
textarea('heading', 'Heading', impressumContent.hero.heading),
|
||||
textarea('descriptionHtml', 'Description HTML', impressumContent.hero.descriptionHtml),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'navigation',
|
||||
label: '02 · Side navigation',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Sticky table-of-contents title and related legal-page link.'),
|
||||
fields: [
|
||||
text('tocTitle', 'TOC title', impressumContent.navigation.tocTitle),
|
||||
text('sideLinkLabel', 'Side link label', impressumContent.navigation.sideLinkLabel),
|
||||
text('sideLinkUrl', 'Side link URL', impressumContent.navigation.sideLinkUrl),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'sections',
|
||||
label: '03 · Legal sections',
|
||||
type: 'array',
|
||||
dbName: 'imp_sections',
|
||||
admin: sectionAdmin('Each section controls one heading, table-of-contents label, and ordered JSON body blocks.'),
|
||||
defaultValue: impressumContent.sections,
|
||||
fields: [
|
||||
text('id', 'Anchor ID'),
|
||||
text('tocLabel', 'TOC label'),
|
||||
text('title', 'Section title'),
|
||||
{
|
||||
name: 'items',
|
||||
label: 'Content blocks JSON',
|
||||
type: 'json',
|
||||
admin: {
|
||||
description:
|
||||
'Array of blocks: paragraph, legal, address, list, or subsection. Paragraph/legal blocks use HTML strings for inline links.',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -10,6 +10,7 @@ import { MediaBlock } from '../../blocks/MediaBlock/config'
|
||||
import { hero } from '@/heros/config'
|
||||
import { contactFields } from './contactFields'
|
||||
import { homeFields } from './homeFields'
|
||||
import { impressumFields } from './impressumFields'
|
||||
import { participationFields } from './participationFields'
|
||||
import { slugField } from 'payload'
|
||||
import { populatePublishedAt } from '../../hooks/populatePublishedAt'
|
||||
@@ -48,8 +49,19 @@ const isParticipationPage = (_: unknown, siblingData?: { slug?: string; spaPath?
|
||||
return spaPath === '/teilnahme' || slug === 'teilnahme' || slug === 'participation' || title === 'teilnahme' || title === 'participation'
|
||||
}
|
||||
|
||||
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 isManagedSpaPage = (_: unknown, siblingData?: { slug?: string; spaPath?: string; title?: string }) =>
|
||||
isHomePage(undefined, siblingData) || isContactPage(undefined, siblingData) || isParticipationPage(undefined, siblingData)
|
||||
isHomePage(undefined, siblingData) ||
|
||||
isContactPage(undefined, siblingData) ||
|
||||
isParticipationPage(undefined, siblingData) ||
|
||||
isImpressumPage(undefined, siblingData)
|
||||
|
||||
export const Pages: CollectionConfig<'pages'> = {
|
||||
slug: 'pages',
|
||||
@@ -138,6 +150,13 @@ export const Pages: CollectionConfig<'pages'> = {
|
||||
fields: participationFields,
|
||||
label: 'Participation Page',
|
||||
},
|
||||
{
|
||||
admin: {
|
||||
condition: (data) => isImpressumPage(undefined, data),
|
||||
},
|
||||
fields: impressumFields,
|
||||
label: 'Impressum Page',
|
||||
},
|
||||
{
|
||||
name: 'meta',
|
||||
label: 'SEO',
|
||||
|
||||
Reference in New Issue
Block a user