feat: manage membership page via payload
This commit is contained in:
@@ -14,6 +14,7 @@ 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'
|
||||
@@ -111,6 +112,14 @@ const isNetzwerkPage = (_: unknown, siblingData?: { slug?: string; spaPath?: str
|
||||
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) ||
|
||||
@@ -121,7 +130,8 @@ const isManagedSpaPage = (_: unknown, siblingData?: { slug?: string; spaPath?: s
|
||||
isPreistraegerIndexPage(undefined, siblingData) ||
|
||||
isPressIndexPage(undefined, siblingData) ||
|
||||
isFormularUploadPage(undefined, siblingData) ||
|
||||
isNetzwerkPage(undefined, siblingData)
|
||||
isNetzwerkPage(undefined, siblingData) ||
|
||||
isMitgliedWerdenPage(undefined, siblingData)
|
||||
|
||||
export const Pages: CollectionConfig<'pages'> = {
|
||||
slug: 'pages',
|
||||
@@ -259,6 +269,13 @@ export const Pages: CollectionConfig<'pages'> = {
|
||||
fields: netzwerkFields,
|
||||
label: 'Network Page',
|
||||
},
|
||||
{
|
||||
admin: {
|
||||
condition: (data) => isMitgliedWerdenPage(undefined, data),
|
||||
},
|
||||
fields: mitgliedWerdenFields,
|
||||
label: 'Membership Page',
|
||||
},
|
||||
{
|
||||
name: 'meta',
|
||||
label: 'SEO',
|
||||
|
||||
303
src/collections/Pages/mitgliedWerdenFields.ts
Normal file
303
src/collections/Pages/mitgliedWerdenFields.ts
Normal file
@@ -0,0 +1,303 @@
|
||||
import type { Field } from 'payload'
|
||||
|
||||
import { mitgliedWerdenContent } from '@/spa/mitgliedWerdenContent'
|
||||
|
||||
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 numberField = (name: string, label: string, defaultValue?: number): Field => ({
|
||||
name,
|
||||
type: 'number',
|
||||
label,
|
||||
defaultValue,
|
||||
})
|
||||
|
||||
const checkbox = (name: string, label: string, defaultValue?: boolean): Field => ({
|
||||
name,
|
||||
type: 'checkbox',
|
||||
label,
|
||||
defaultValue,
|
||||
})
|
||||
|
||||
const uploadField = (name: string, label: string, description?: string): Field => ({
|
||||
name,
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
label,
|
||||
admin: description ? { description } : undefined,
|
||||
})
|
||||
|
||||
const sectionAdmin = (description: string) => ({
|
||||
description,
|
||||
initCollapsed: true,
|
||||
})
|
||||
|
||||
const statFields: Field[] = [text('value', 'Value'), text('label', 'Label')]
|
||||
const factFields: Field[] = [text('num', 'Number'), text('label', 'Label'), textarea('body', 'Body')]
|
||||
const faqFields: Field[] = [text('q', 'Question'), textarea('a', 'Answer')]
|
||||
const testimonialFields: Field[] = [
|
||||
textarea('quote', 'Quote'),
|
||||
text('initials', 'Initials'),
|
||||
text('name', 'Name'),
|
||||
text('role', 'Role'),
|
||||
]
|
||||
|
||||
export const mitgliedWerdenFields: Field[] = [
|
||||
{
|
||||
name: 'mitgliedWerden',
|
||||
label: 'Membership page content',
|
||||
type: 'group',
|
||||
admin: {
|
||||
description:
|
||||
'Edit the Mitglied werden page sections, pricing model, application choices, FAQ, testimonials, and wizard copy.',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'header',
|
||||
label: '00 · Header',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Small top bar brand and return link.'),
|
||||
fields: [
|
||||
text('brandLabel', 'Brand label', mitgliedWerdenContent.header.brandLabel),
|
||||
text('backLabel', 'Back link label', mitgliedWerdenContent.header.backLabel),
|
||||
text('backUrl', 'Back link URL', mitgliedWerdenContent.header.backUrl),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'hero',
|
||||
label: '01 · Hero',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Hero image, headline, description, and desktop stats.'),
|
||||
fields: [
|
||||
uploadField('image', 'Hero image', `Current frontend image: /images/${mitgliedWerdenContent.hero.imageFilename}`),
|
||||
text('imageAlt', 'Image alt text', mitgliedWerdenContent.hero.imageAlt),
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.hero.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.hero.heading),
|
||||
textarea('description', 'Description', mitgliedWerdenContent.hero.description),
|
||||
{
|
||||
name: 'stats',
|
||||
label: 'Stats',
|
||||
type: 'array',
|
||||
dbName: 'member_hero_stats',
|
||||
defaultValue: mitgliedWerdenContent.hero.stats,
|
||||
fields: statFields,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'benefits',
|
||||
label: '02 · Benefits',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Benefit section heading and cards. Icon choices map to Lucide icons in the SPA.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.benefits.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.benefits.heading),
|
||||
{
|
||||
name: 'cards',
|
||||
label: 'Cards',
|
||||
type: 'array',
|
||||
dbName: 'member_benefits',
|
||||
defaultValue: mitgliedWerdenContent.benefits.cards,
|
||||
fields: [
|
||||
{
|
||||
name: 'icon',
|
||||
label: 'Icon',
|
||||
type: 'select',
|
||||
defaultValue: 'users',
|
||||
options: [
|
||||
{ label: 'Users', value: 'users' },
|
||||
{ label: 'Star', value: 'star' },
|
||||
{ label: 'Eye', value: 'eye' },
|
||||
{ label: 'Heart', value: 'heart' },
|
||||
],
|
||||
},
|
||||
text('title', 'Title'),
|
||||
textarea('body', 'Body'),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'about',
|
||||
label: '03 · About',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Association explainer, descriptor, and fact rows.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.about.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.about.heading),
|
||||
{
|
||||
name: 'paragraphs',
|
||||
label: 'Paragraphs',
|
||||
type: 'array',
|
||||
dbName: 'member_about_copy',
|
||||
defaultValue: mitgliedWerdenContent.about.paragraphs.map((text) => ({ text })),
|
||||
fields: [textarea('text', 'Text')],
|
||||
},
|
||||
text('descriptor', 'Descriptor', mitgliedWerdenContent.about.descriptor),
|
||||
{
|
||||
name: 'facts',
|
||||
label: 'Facts',
|
||||
type: 'array',
|
||||
dbName: 'member_about_facts',
|
||||
defaultValue: mitgliedWerdenContent.about.facts,
|
||||
fields: factFields,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'pricing',
|
||||
label: '04 · Pricing calculator',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Calculator labels, table copy, VAT rate, admission fee, and tier rows.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.pricing.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.pricing.heading),
|
||||
text('employeeLabel', 'Employee select label', mitgliedWerdenContent.pricing.employeeLabel),
|
||||
text('selectPlaceholder', 'Select placeholder', mitgliedWerdenContent.pricing.selectPlaceholder),
|
||||
text('optionSuffix', 'Option suffix', mitgliedWerdenContent.pricing.optionSuffix),
|
||||
text('resultEyebrow', 'Result eyebrow', mitgliedWerdenContent.pricing.resultEyebrow),
|
||||
text('annualNetLabel', 'Annual net label', mitgliedWerdenContent.pricing.annualNetLabel),
|
||||
text('annualGrossLabel', 'Annual gross label', mitgliedWerdenContent.pricing.annualGrossLabel),
|
||||
text('annualGrossShortLabel', 'Annual gross short label', mitgliedWerdenContent.pricing.annualGrossShortLabel),
|
||||
text('admissionGrossLabel', 'Admission gross label', mitgliedWerdenContent.pricing.admissionGrossLabel),
|
||||
text('totalYearOneLabel', 'Total year-one label', mitgliedWerdenContent.pricing.totalYearOneLabel),
|
||||
textarea('footnote', 'Footnote', mitgliedWerdenContent.pricing.footnote),
|
||||
text('ctaLabel', 'CTA label', mitgliedWerdenContent.pricing.ctaLabel),
|
||||
text('ctaHref', 'CTA URL', mitgliedWerdenContent.pricing.ctaHref),
|
||||
text('tableToggleLabel', 'Table toggle label', mitgliedWerdenContent.pricing.tableToggleLabel),
|
||||
text('tableEmployeeHeader', 'Table employees header', mitgliedWerdenContent.pricing.tableEmployeeHeader),
|
||||
text('tableNetHeader', 'Table net header', mitgliedWerdenContent.pricing.tableNetHeader),
|
||||
text('tableGrossHeader', 'Table gross header', mitgliedWerdenContent.pricing.tableGrossHeader),
|
||||
text('tableNotePrefix', 'Table note prefix', mitgliedWerdenContent.pricing.tableNotePrefix),
|
||||
text('tableNoteSuffix', 'Table note suffix', mitgliedWerdenContent.pricing.tableNoteSuffix),
|
||||
numberField('vatRate', 'VAT rate', mitgliedWerdenContent.pricing.vatRate),
|
||||
numberField('admissionFeeNet', 'Admission fee net', mitgliedWerdenContent.pricing.admissionFeeNet),
|
||||
{
|
||||
name: 'tiers',
|
||||
label: 'Tiers',
|
||||
type: 'array',
|
||||
dbName: 'member_pricing',
|
||||
defaultValue: mitgliedWerdenContent.pricing.tiers,
|
||||
fields: [numberField('max', 'Maximum employees'), text('label', 'Label'), numberField('annual', 'Annual net amount')],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'applicationOptions',
|
||||
label: '05 · Application options',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Online and PDF application strip.'),
|
||||
fields: [
|
||||
{
|
||||
name: 'items',
|
||||
label: 'Options',
|
||||
type: 'array',
|
||||
dbName: 'member_app_options',
|
||||
defaultValue: mitgliedWerdenContent.applicationOptions.items,
|
||||
fields: [
|
||||
text('id', 'Stable ID'),
|
||||
text('number', 'Number'),
|
||||
text('eyebrow', 'Eyebrow'),
|
||||
text('title', 'Title'),
|
||||
textarea('description', 'Description'),
|
||||
text('href', 'URL'),
|
||||
uploadField('file', 'Download file'),
|
||||
checkbox('download', 'Download link'),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'formIntro',
|
||||
label: '06 · Form intro',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Left-hand pitch copy and wizard image/caption.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.formIntro.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.formIntro.heading),
|
||||
textarea('description', 'Description', mitgliedWerdenContent.formIntro.description),
|
||||
{
|
||||
name: 'promises',
|
||||
label: 'Promise rows',
|
||||
type: 'array',
|
||||
dbName: 'member_promises',
|
||||
defaultValue: mitgliedWerdenContent.formIntro.promises,
|
||||
fields: [text('num', 'Number'), text('label', 'Label'), text('desc', 'Description')],
|
||||
},
|
||||
uploadField('image', 'Wizard image', `Current frontend image: /images/${mitgliedWerdenContent.formIntro.imageFilename}`),
|
||||
text('imageAlt', 'Image alt text', mitgliedWerdenContent.formIntro.imageAlt),
|
||||
text('imageLabel', 'Image caption', mitgliedWerdenContent.formIntro.imageLabel),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'wizard',
|
||||
label: '07 · Wizard copy JSON',
|
||||
type: 'json',
|
||||
admin: {
|
||||
description:
|
||||
'Deep wizard labels, options, validation messages, legal text, consent copy, success copy, and duplicated pricing defaults. Keep the object shape aligned with src/spa/mitgliedWerdenContent.ts.',
|
||||
},
|
||||
defaultValue: mitgliedWerdenContent.wizard,
|
||||
},
|
||||
{
|
||||
name: 'testimonials',
|
||||
label: '08 · Testimonials',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Member quotes and attribution cards.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.testimonials.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.testimonials.heading),
|
||||
{
|
||||
name: 'items',
|
||||
label: 'Quotes',
|
||||
type: 'array',
|
||||
dbName: 'member_quotes',
|
||||
defaultValue: mitgliedWerdenContent.testimonials.items,
|
||||
fields: testimonialFields,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'faq',
|
||||
label: '09 · FAQ',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('FAQ heading and question/answer rows.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.faq.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.faq.heading),
|
||||
{
|
||||
name: 'items',
|
||||
label: 'Items',
|
||||
type: 'array',
|
||||
dbName: 'member_faq',
|
||||
defaultValue: mitgliedWerdenContent.faq.items,
|
||||
fields: faqFields,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'bottomCta',
|
||||
label: '10 · Bottom CTA',
|
||||
type: 'group',
|
||||
admin: sectionAdmin('Final call-to-action band.'),
|
||||
fields: [
|
||||
text('eyebrow', 'Eyebrow', mitgliedWerdenContent.bottomCta.eyebrow),
|
||||
textarea('heading', 'Heading', mitgliedWerdenContent.bottomCta.heading),
|
||||
text('ctaLabel', 'CTA label', mitgliedWerdenContent.bottomCta.ctaLabel),
|
||||
text('ctaHref', 'CTA URL', mitgliedWerdenContent.bottomCta.ctaHref),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user