Files
bmp-website-2026/src/collections/Pages/homeFields.ts
2026-06-22 12:10:45 +02:00

249 lines
11 KiB
TypeScript

import type { Field } from 'payload'
import { homeContent } from '@/spa/homeContent'
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 linkGroup = (labelDefault: string, urlDefault: string): Field[] => [
text('label', 'Button text', labelDefault),
text('url', 'Link URL', urlDefault),
]
const sectionAdmin = (description: string) => ({
description,
initCollapsed: true,
})
export const homeFields: Field[] = [
{
name: 'home',
label: 'Home page layout sections',
type: 'group',
admin: {
description:
'Edit the homepage in the same order it appears on the frontend. The generic Hero and Content tabs are hidden for the home page to avoid duplicate controls.',
},
fields: [
{
name: 'hero',
label: '01 · Hero / opening screen',
type: 'group',
admin: sectionAdmin('Top full-screen gala image, badge, headline, intro text, primary buttons, video trigger, and partner ticker.'),
fields: [
uploadField('backgroundImage', 'Background image', `Current frontend image: /images/${homeContent.hero.backgroundImageFilename}`),
text('imageAlt', 'Image alt text', homeContent.hero.imageAlt),
text('badge', 'Badge text', homeContent.hero.badge),
text('headingLine1', 'Headline line 1', homeContent.hero.headingLine1),
text('headingAccent', 'Headline accent line', homeContent.hero.headingAccent),
textarea(
'description',
'Intro paragraph',
homeContent.hero.description,
),
{ name: 'primaryCta', label: 'Primary CTA', type: 'group', fields: linkGroup(homeContent.hero.primaryCta.label, homeContent.hero.primaryCta.url) },
{ name: 'secondaryCta', label: 'Secondary CTA', type: 'group', fields: linkGroup(homeContent.hero.secondaryCta.label, homeContent.hero.secondaryCta.url) },
text('videoLabel', 'Video button label', homeContent.hero.videoLabel),
text('partnersLabel', 'Partner ticker label', homeContent.hero.partnersLabel),
{
name: 'partners',
label: 'Partner ticker names',
type: 'array',
defaultValue: homeContent.hero.partners,
fields: [text('name', 'Name')],
},
],
},
{
name: 'quickCheck',
label: '02 · Schnell-Check eligibility section',
type: 'group',
admin: sectionAdmin('Cream text panel plus right-side stage image and five eligibility rows.'),
fields: [
text('eyebrow', 'Eyebrow', homeContent.quickCheck.eyebrow),
textarea('heading', 'Heading', homeContent.quickCheck.heading),
uploadField('image', 'Image', `Current frontend image: /images/${homeContent.quickCheck.imageFilename}`),
text('imageAlt', 'Image alt text', homeContent.quickCheck.imageAlt),
textarea(
'body',
'Body copy',
homeContent.quickCheck.body,
),
{
name: 'criteria',
label: 'Criteria rows',
type: 'array',
defaultValue: homeContent.quickCheck.criteria,
fields: [text('label', 'Criterion'), text('desc', 'Description')],
},
textarea(
'note',
'Small note below criteria',
homeContent.quickCheck.note,
),
{ name: 'cta', label: 'CTA', type: 'group', fields: linkGroup(homeContent.quickCheck.cta.label, homeContent.quickCheck.cta.url) },
],
},
{
name: 'intro',
label: '03 · Award intro / value proposition',
type: 'group',
admin: sectionAdmin('Jubilation image, stats, editorial quote, body copy, and CTA.'),
fields: [
text('eyebrow', 'Eyebrow', homeContent.intro.eyebrow),
textarea('heading', 'Heading', homeContent.intro.heading),
uploadField('image', 'Image', `Current frontend image: /images/${homeContent.intro.imageFilename}`),
text('imageAlt', 'Image alt text', homeContent.intro.imageAlt),
{
name: 'stats',
label: 'Stats',
type: 'array',
defaultValue: homeContent.intro.stats,
fields: [text('value', 'Value'), text('label', 'Label')],
},
textarea('quote', 'Quote', homeContent.intro.quote),
textarea(
'body',
'Body copy',
homeContent.intro.body,
),
{ name: 'cta', label: 'CTA', type: 'group', fields: linkGroup(homeContent.intro.cta.label, homeContent.intro.cta.url) },
],
},
{
name: 'status',
label: '04 · Application phase slider',
type: 'group',
admin: sectionAdmin('Three-slide status module shown after the award intro.'),
fields: [
{
name: 'activePhase',
label: 'Current phase shown on the homepage',
type: 'select',
defaultValue: homeContent.status.activePhase,
options: [
{ label: '01 · Bewerbungsphase offen', value: '0' },
{ label: '02 · Auswertung / Jury bewertet', value: '1' },
{ label: '03 · Preisverleihung abgeschlossen', value: '2' },
],
admin: { description: 'Only this selected phase is rendered on the frontend; visitors do not see a slider.' },
},
{
name: 'phases',
label: 'Slides',
type: 'array',
maxRows: 3,
defaultValue: homeContent.status.phases,
fields: [
text('num', 'Slide number'), text('tag', 'Badge'), { name: 'pulse', label: 'Show pulse dot', type: 'checkbox', defaultValue: true }, text('phase', 'Phase label'), text('headline', 'Headline'), textarea('body', 'Body copy'),
{ name: 'cta', label: 'Slide CTA', type: 'group', fields: linkGroup('', '') }, text('accent', 'Accent color'), text('bg', 'Background color'), text('glow', 'Glow color'), text('meta', 'Meta label'), text('successApplications', 'Success applications number'), text('successWinners', 'Success winners number'), { name: 'membershipCta', label: 'Membership CTA', type: 'group', fields: linkGroup('Mitglied werden', '/mitglied-werden') },
],
},
text('noActionLabel', 'No CTA fallback label', homeContent.status.noActionLabel),
text('successApplicationsLabel', 'Success applications label', homeContent.status.successApplicationsLabel),
text('successWinnersLabel', 'Success winners label', homeContent.status.successWinnersLabel),
],
},
{
name: 'winners',
label: '05 · Preisträger card grid',
type: 'group',
admin: sectionAdmin('Blue card grid with featured winner relationships.'),
fields: [
text('eyebrow', 'Eyebrow', homeContent.winners.eyebrow),
textarea('heading', 'Heading', homeContent.winners.heading),
{ name: 'cta', label: 'CTA', type: 'group', fields: linkGroup(homeContent.winners.cta.label, homeContent.winners.cta.url) },
uploadField('fallbackImage', 'Fallback card image', `Current frontend image: /images/${homeContent.winners.fallbackImageFilename}`),
text('cardFallbackTitle', 'Fallback card title', homeContent.winners.cardFallbackTitle),
text('hoverLabel', 'Card hover label', homeContent.winners.hoverLabel),
{
name: 'featured',
label: 'Featured winner cards',
type: 'relationship',
relationTo: 'preistraeger',
hasMany: true,
admin: { description: 'Choose the winner cards shown on the home page. If empty, the latest 2025 winners are used.' },
},
],
},
{
name: 'testimonials',
label: '06 · Testimonials carousel',
type: 'group',
admin: sectionAdmin('Portrait carousel and quote copy.'),
fields: [
text('eyebrow', 'Eyebrow', homeContent.testimonials.eyebrow),
textarea('heading', 'Heading', homeContent.testimonials.heading),
{
name: 'items',
label: 'Testimonials',
type: 'array',
defaultValue: homeContent.testimonials.items,
fields: [uploadField('image', 'Portrait image'), text('imageUrl', 'External image URL'), text('name', 'Name'), text('role', 'Role'), text('company', 'Company'), text('year', 'Year'), textarea('quote', 'Quote')],
},
],
},
{
name: 'benefits',
label: '07 · Participation benefits',
type: 'group',
admin: sectionAdmin('Cream left panel and networking image.'),
fields: [
text('eyebrow', 'Eyebrow', homeContent.benefits.eyebrow),
textarea('heading', 'Heading', homeContent.benefits.heading),
uploadField('image', 'Image', `Current frontend image: /images/${homeContent.benefits.imageFilename}`),
text('imageAlt', 'Image alt text', homeContent.benefits.imageAlt),
text('imageLabel', 'Desktop image label', homeContent.benefits.imageLabel),
{
name: 'items', label: 'Benefit rows', type: 'array', defaultValue: homeContent.benefits.items, fields: [text('num', 'Number'), text('title', 'Title'), textarea('desc', 'Description')],
},
],
},
{
name: 'application',
label: '08 · Application form section',
type: 'group',
admin: sectionAdmin('Final application pitch, award image, embedded form heading, and footnote.'),
fields: [
text('eyebrow', 'Eyebrow', homeContent.application.eyebrow),
textarea('heading', 'Heading', homeContent.application.heading),
textarea('body', 'Body copy', homeContent.application.body),
{ name: 'benefits', label: 'Benefit rows', type: 'array', defaultValue: homeContent.application.benefits, fields: [text('num', 'Number'), text('label', 'Label'), text('desc', 'Description')] },
uploadField('awardImage', 'Award image', `Current frontend image: /images/${homeContent.application.awardImageFilename}`),
text('awardImageAlt', 'Award image alt text', homeContent.application.awardImageAlt),
text('awardCaption', 'Award image caption', homeContent.application.awardCaption),
text('formEyebrow', 'Form eyebrow', homeContent.application.formEyebrow),
text('formTitle', 'Form title', homeContent.application.formTitle),
text('footnote', 'Footnote normal text', homeContent.application.footnote),
text('footnoteStrong', 'Footnote highlighted text', homeContent.application.footnoteStrong),
],
},
{
name: 'videoModal',
label: '09 · Video modal placeholder',
type: 'group',
admin: sectionAdmin('Copy shown when the hero video button is clicked.'),
fields: [text('title', 'Title', homeContent.videoModal.title), text('description', 'Description', homeContent.videoModal.description), text('closeLabel', 'Close button label', homeContent.videoModal.closeLabel)],
},
],
},
]