271 lines
10 KiB
TypeScript
271 lines
10 KiB
TypeScript
import type { Field } from 'payload'
|
|
|
|
import { aboutContent } from '@/spa/aboutContent'
|
|
|
|
const uploadField = (name: string, label: string, description?: string): Field => ({
|
|
name,
|
|
type: 'upload',
|
|
relationTo: 'media',
|
|
label,
|
|
admin: description ? { description } : undefined,
|
|
})
|
|
|
|
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 ctaGroup = (name: string, label: string, labelDefault: string, urlDefault: string): Field => ({
|
|
name,
|
|
label,
|
|
type: 'group',
|
|
fields: [text('label', 'Label', labelDefault), text('url', 'URL', urlDefault)],
|
|
})
|
|
|
|
const sectionAdmin = (description: string) => ({
|
|
description,
|
|
initCollapsed: true,
|
|
})
|
|
|
|
const statFields: Field[] = [text('value', 'Value'), text('label', 'Label')]
|
|
const bodyFields: Field[] = [textarea('text', 'Paragraph')]
|
|
const numberedFields: Field[] = [text('num', 'Number'), text('title', 'Title'), textarea('desc', 'Description')]
|
|
|
|
export const aboutFields: Field[] = [
|
|
{
|
|
name: 'about',
|
|
label: 'About / Der BMP page layout sections',
|
|
type: 'group',
|
|
admin: {
|
|
description:
|
|
'Edit the Der BMP page in the same order it appears on the frontend. The generic Hero and Content tabs are hidden for this SPA-managed route.',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'hero',
|
|
label: '01 · Hero',
|
|
type: 'group',
|
|
admin: sectionAdmin('Top hero image, headline, CTAs, and stats strip.'),
|
|
fields: [
|
|
uploadField('backgroundImage', 'Background image', `Current frontend image: /images/${aboutContent.hero.backgroundImageFilename}`),
|
|
text('imageAlt', 'Image alt text', aboutContent.hero.imageAlt),
|
|
text('eyebrow', 'Eyebrow', aboutContent.hero.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.hero.heading),
|
|
text('highlight', 'Highlighted heading line', aboutContent.hero.highlight),
|
|
textarea('description', 'Intro paragraph', aboutContent.hero.description),
|
|
ctaGroup('primaryCta', 'Primary CTA', aboutContent.hero.primaryCta.label, aboutContent.hero.primaryCta.url),
|
|
ctaGroup('secondaryCta', 'Secondary CTA', aboutContent.hero.secondaryCta.label, aboutContent.hero.secondaryCta.url),
|
|
{
|
|
name: 'stats',
|
|
label: 'Stats',
|
|
type: 'array',
|
|
dbName: 'about_hero_stats',
|
|
defaultValue: aboutContent.hero.stats,
|
|
fields: statFields,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'prize',
|
|
label: '02 · Was ist der Preis?',
|
|
type: 'group',
|
|
admin: sectionAdmin('Cream text/image section explaining the prize.'),
|
|
fields: [
|
|
uploadField('image', 'Image', `Current frontend image: /images/${aboutContent.prize.imageFilename}`),
|
|
text('imageAlt', 'Image alt text', aboutContent.prize.imageAlt),
|
|
text('eyebrow', 'Eyebrow', aboutContent.prize.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.prize.heading),
|
|
{
|
|
name: 'body',
|
|
label: 'Body paragraphs',
|
|
type: 'array',
|
|
dbName: 'about_prize_body',
|
|
defaultValue: aboutContent.prize.body.map((text) => ({ text })),
|
|
fields: bodyFields,
|
|
},
|
|
{
|
|
name: 'facts',
|
|
label: 'Key facts',
|
|
type: 'array',
|
|
dbName: 'about_prize_facts',
|
|
defaultValue: aboutContent.prize.facts,
|
|
fields: statFields,
|
|
},
|
|
text('imageLabel', 'Desktop image label', aboutContent.prize.imageLabel),
|
|
],
|
|
},
|
|
{
|
|
name: 'mittelstand',
|
|
label: '03 · Bedeutung für den Mittelstand',
|
|
type: 'group',
|
|
admin: sectionAdmin('Navy text/image section about relevance and goals.'),
|
|
fields: [
|
|
uploadField('image', 'Image', `Current frontend image: /images/${aboutContent.mittelstand.imageFilename}`),
|
|
text('imageAlt', 'Image alt text', aboutContent.mittelstand.imageAlt),
|
|
text('eyebrow', 'Eyebrow', aboutContent.mittelstand.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.mittelstand.heading),
|
|
{
|
|
name: 'body',
|
|
label: 'Body paragraphs',
|
|
type: 'array',
|
|
dbName: 'about_mid_body',
|
|
defaultValue: aboutContent.mittelstand.body.map((text) => ({ text })),
|
|
fields: bodyFields,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'highlights',
|
|
label: '04 · Preisträger highlights',
|
|
type: 'group',
|
|
admin: sectionAdmin('Header copy and editor-selected winners for the photo grid.'),
|
|
fields: [
|
|
uploadField('fallbackImage', 'Fallback winner image', `Current frontend fallback image: /images/${aboutContent.highlights.fallbackImageFilename}`),
|
|
text('eyebrow', 'Eyebrow', aboutContent.highlights.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.highlights.heading),
|
|
ctaGroup('cta', 'CTA', aboutContent.highlights.cta.label, aboutContent.highlights.cta.url),
|
|
text('hoverLabel', 'Card hover label', aboutContent.highlights.hoverLabel),
|
|
{
|
|
name: 'fallbackWinner',
|
|
label: 'Fallback winner text',
|
|
type: 'group',
|
|
fields: [
|
|
text('name', 'Name fallback', aboutContent.highlights.fallbackWinner.name),
|
|
text('category', 'Category fallback', aboutContent.highlights.fallbackWinner.category),
|
|
text('awardType', 'Award type fallback', aboutContent.highlights.fallbackWinner.awardType),
|
|
],
|
|
},
|
|
{
|
|
name: 'year',
|
|
label: 'Fallback winner year',
|
|
type: 'number',
|
|
defaultValue: aboutContent.highlights.year,
|
|
},
|
|
{
|
|
name: 'selectedWinners',
|
|
label: 'Selected winners',
|
|
type: 'relationship',
|
|
relationTo: 'preistraeger',
|
|
hasMany: true,
|
|
maxRows: 8,
|
|
admin: {
|
|
description: 'Choose up to 8 Preisträger to show. If empty, the frontend falls back to winners from the selected year.',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'testimonials',
|
|
label: '05 · Testimonials',
|
|
type: 'group',
|
|
admin: sectionAdmin('Testimonial heading and slides. Upload images when available, or keep the migrated URL fallback.'),
|
|
fields: [
|
|
text('eyebrow', 'Eyebrow', aboutContent.testimonials.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.testimonials.heading),
|
|
textarea('desktopHeading', 'Desktop heading', aboutContent.testimonials.desktopHeading),
|
|
text('yearPrefix', 'Award year prefix', aboutContent.testimonials.yearPrefix),
|
|
text('previousLabel', 'Previous button label', aboutContent.testimonials.previousLabel),
|
|
text('nextLabel', 'Next button label', aboutContent.testimonials.nextLabel),
|
|
text('slideLabelPrefix', 'Slide dot label prefix', aboutContent.testimonials.slideLabelPrefix),
|
|
{
|
|
name: 'items',
|
|
label: 'Testimonials',
|
|
type: 'array',
|
|
dbName: 'about_tst_items',
|
|
defaultValue: aboutContent.testimonials.items,
|
|
fields: [
|
|
uploadField('image', 'Image'),
|
|
text('imageUrl', 'Fallback image URL'),
|
|
text('name', 'Name'),
|
|
text('role', 'Role'),
|
|
text('company', 'Company'),
|
|
text('year', 'Award year'),
|
|
textarea('quote', 'Quote'),
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'history',
|
|
label: '06 · Geschichte & Meilensteine',
|
|
type: 'group',
|
|
admin: sectionAdmin('Navy timeline section.'),
|
|
fields: [
|
|
text('eyebrow', 'Eyebrow', aboutContent.history.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.history.heading),
|
|
text('highlight', 'Highlighted heading word', aboutContent.history.highlight),
|
|
text('watermark', 'Desktop watermark', aboutContent.history.watermark),
|
|
{
|
|
name: 'items',
|
|
label: 'Timeline items',
|
|
type: 'array',
|
|
dbName: 'about_hist_items',
|
|
defaultValue: aboutContent.history.items,
|
|
fields: [text('year', 'Year'), text('title', 'Title'), textarea('desc', 'Description')],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'goals',
|
|
label: '07 · Zielsetzung',
|
|
type: 'group',
|
|
admin: sectionAdmin('Cream values list next to the history timeline.'),
|
|
fields: [
|
|
text('eyebrow', 'Eyebrow', aboutContent.goals.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.goals.heading),
|
|
{
|
|
name: 'items',
|
|
label: 'Goal rows',
|
|
type: 'array',
|
|
dbName: 'about_goal_items',
|
|
defaultValue: aboutContent.goals.items,
|
|
fields: numberedFields,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'values',
|
|
label: '08 · Vorteile & Werte',
|
|
type: 'group',
|
|
admin: sectionAdmin('Cream editorial rows before the final CTA.'),
|
|
fields: [
|
|
text('eyebrow', 'Eyebrow', aboutContent.values.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.values.heading),
|
|
textarea('description', 'Description', aboutContent.values.description),
|
|
{
|
|
name: 'items',
|
|
label: 'Value rows',
|
|
type: 'array',
|
|
dbName: 'about_val_items',
|
|
defaultValue: aboutContent.values.items,
|
|
fields: [text('num', 'Number'), text('title', 'Title')],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'cta',
|
|
label: '09 · Final CTA',
|
|
type: 'group',
|
|
admin: sectionAdmin('Bottom navy CTA section.'),
|
|
fields: [
|
|
text('eyebrow', 'Eyebrow', aboutContent.cta.eyebrow),
|
|
textarea('heading', 'Heading', aboutContent.cta.heading),
|
|
textarea('description', 'Description', aboutContent.cta.description),
|
|
ctaGroup('primaryCta', 'Primary CTA', aboutContent.cta.primaryCta.label, aboutContent.cta.primaryCta.url),
|
|
text('secondaryPrefix', 'Secondary prefix', aboutContent.cta.secondaryPrefix),
|
|
ctaGroup('secondaryCta', 'Secondary CTA', aboutContent.cta.secondaryCta.label, aboutContent.cta.secondaryCta.url),
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]
|