diff --git a/src/collections/Pages/homeFields.ts b/src/collections/Pages/homeFields.ts index a0b935f..b5cc1aa 100644 --- a/src/collections/Pages/homeFields.ts +++ b/src/collections/Pages/homeFields.ts @@ -33,6 +33,33 @@ const sectionAdmin = (description: string) => ({ initCollapsed: true, }) +const iconOptions = [ + { label: 'Alert circle', value: 'alertCircle' }, + { label: 'Arrow right', value: 'arrowRight' }, + { label: 'Building', value: 'building2' }, + { label: 'Check', value: 'check' }, + { label: 'Check circle', value: 'checkCircle2' }, + { label: 'File text', value: 'fileText' }, + { label: 'Map pin', value: 'mapPin' }, + { label: 'Search', value: 'search' }, + { label: 'Send', value: 'send' }, + { label: 'Star', value: 'star' }, + { label: 'Trending up', value: 'trendingUp' }, + { label: 'Trophy', value: 'trophy' }, + { label: 'User', value: 'user' }, + { label: 'User check', value: 'userCheck' }, + { label: 'User plus', value: 'userPlus' }, + { label: 'Users', value: 'users' }, +] + +const iconField = (defaultValue = 'star'): Field => ({ + name: 'icon', + label: 'Icon', + type: 'select', + defaultValue, + options: iconOptions, +}) + export const homeFields: Field[] = [ { name: 'home', @@ -236,9 +263,125 @@ export const homeFields: Field[] = [ text('footnoteStrong', 'Footnote highlighted text', homeContent.application.footnoteStrong), ], }, + { + name: 'form', + label: '09 · Embedded application form copy and logic labels', + type: 'group', + admin: sectionAdmin('Text, options, and eligibility thresholds used inside the home page multi-step application form.'), + fields: [ + text('stepCompleteLabel', 'Completed step label', homeContent.form.stepCompleteLabel), + text('backLabel', 'Back button label', homeContent.form.backLabel), + text('nextLabel', 'Next button label', homeContent.form.nextLabel), + text('submitLabel', 'Submit button label', homeContent.form.submitLabel), + text('yesLabel', 'Yes option label', homeContent.form.yesLabel), + text('noLabel', 'No option label', homeContent.form.noLabel), + text('requiredSuffix', 'Required field suffix', homeContent.form.requiredSuffix), + { + name: 'validation', + label: 'Validation messages', + type: 'group', + fields: [ + text('choose', 'Choose message', homeContent.form.validation.choose), + text('required', 'Required message', homeContent.form.validation.required), + text('invalidEmail', 'Invalid email message', homeContent.form.validation.invalidEmail), + ], + }, + { + name: 'typeStep', + label: 'Step 1 · Submission type', + type: 'group', + fields: [ + text('eyebrow', 'Eyebrow', homeContent.form.typeStep.eyebrow), + text('heading', 'Heading', homeContent.form.typeStep.heading), + text('selfTitle', 'Self-application title', homeContent.form.typeStep.selfTitle), + textarea('selfDesc', 'Self-application description', homeContent.form.typeStep.selfDesc), + text('nominationTitle', 'Nomination title', homeContent.form.typeStep.nominationTitle), + textarea('nominationDesc', 'Nomination description', homeContent.form.typeStep.nominationDesc), + ], + }, + { + name: 'selfSteps', + label: 'Self-application step labels', + type: 'array', + dbName: 'home_self_steps', + defaultValue: homeContent.form.selfSteps, + fields: [text('label', 'Label'), iconField('trophy')], + }, + { + name: 'nominationSteps', + label: 'Nomination step labels', + type: 'array', + dbName: 'home_nom_steps', + defaultValue: homeContent.form.nominationSteps, + fields: [text('label', 'Label'), iconField('trophy')], + }, + { + name: 'employeeOptions', + label: 'Employee options', + type: 'array', + dbName: 'home_emp_opts', + defaultValue: homeContent.form.employeeOptions, + fields: [text('value', 'Value'), text('label', 'Label')], + }, + { + name: 'eligibility', + label: 'Self-application eligibility step', + type: 'group', + fields: [ + text('allowedEmployeeValues', 'Allowed employee option values, comma-separated', homeContent.form.eligibility.allowedEmployeeValues), + text('requiredBayernValue', 'Required Bavaria answer value', homeContent.form.eligibility.requiredBayernValue), + text('eyebrow', 'Eyebrow', homeContent.form.eligibility.eyebrow), + text('heading', 'Heading', homeContent.form.eligibility.heading), + text('employeesLabel', 'Employees field label', homeContent.form.eligibility.employeesLabel), + text('bayernLabel', 'Bavaria field label', homeContent.form.eligibility.bayernLabel), + text('ownerLabel', 'Owner field label', homeContent.form.eligibility.ownerLabel), + text('ineligibleHeading', 'Ineligible heading', homeContent.form.eligibility.ineligibleHeading), + textarea('ineligibleBody', 'Ineligible body', homeContent.form.eligibility.ineligibleBody), + text('ineligibleContactPrefix', 'Ineligible contact prefix', homeContent.form.eligibility.ineligibleContactPrefix), + text('ineligibleContactEmail', 'Ineligible contact email', homeContent.form.eligibility.ineligibleContactEmail), + ], + }, + { + name: 'selfContact', + label: 'Self-application contact step', + type: 'group', + fields: Object.entries(homeContent.form.selfContact).map(([name, value]) => text(name, name, value)), + }, + { + name: 'selfSummary', + label: 'Self-application summary step', + type: 'group', + fields: Object.entries(homeContent.form.selfSummary).map(([name, value]) => text(name, name, value)), + }, + { + name: 'nominationCompany', + label: 'Nomination company step', + type: 'group', + fields: Object.entries(homeContent.form.nominationCompany).map(([name, value]) => text(name, name, value)), + }, + { + name: 'nominationContact', + label: 'Nomination contact step', + type: 'group', + fields: Object.entries(homeContent.form.nominationContact).map(([name, value]) => text(name, name, value)), + }, + { + name: 'nominationSummary', + label: 'Nomination summary step', + type: 'group', + fields: Object.entries(homeContent.form.nominationSummary).map(([name, value]) => text(name, name, value)), + }, + { + name: 'success', + label: 'Success state copy', + type: 'group', + fields: Object.entries(homeContent.form.success).map(([name, value]) => text(name, name, value)), + }, + ], + }, { name: 'videoModal', - label: '09 · Video modal placeholder', + label: '10 · 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)], diff --git a/src/payload-types.ts b/src/payload-types.ts index ac6c75c..ddf602c 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -414,6 +414,165 @@ export interface Page { footnote?: string | null; footnoteStrong?: string | null; }; + /** + * Text, options, and eligibility thresholds used inside the home page multi-step application form. + */ + form?: { + stepCompleteLabel?: string | null; + backLabel?: string | null; + nextLabel?: string | null; + submitLabel?: string | null; + yesLabel?: string | null; + noLabel?: string | null; + requiredSuffix?: string | null; + validation?: { + choose?: string | null; + required?: string | null; + invalidEmail?: string | null; + }; + typeStep?: { + eyebrow?: string | null; + heading?: string | null; + selfTitle?: string | null; + selfDesc?: string | null; + nominationTitle?: string | null; + nominationDesc?: string | null; + }; + selfSteps?: + | { + label?: string | null; + icon?: + | ( + | 'alertCircle' + | 'arrowRight' + | 'building2' + | 'check' + | 'checkCircle2' + | 'fileText' + | 'mapPin' + | 'search' + | 'send' + | 'star' + | 'trendingUp' + | 'trophy' + | 'user' + | 'userCheck' + | 'userPlus' + | 'users' + ) + | null; + id?: string | null; + }[] + | null; + nominationSteps?: + | { + label?: string | null; + icon?: + | ( + | 'alertCircle' + | 'arrowRight' + | 'building2' + | 'check' + | 'checkCircle2' + | 'fileText' + | 'mapPin' + | 'search' + | 'send' + | 'star' + | 'trendingUp' + | 'trophy' + | 'user' + | 'userCheck' + | 'userPlus' + | 'users' + ) + | null; + id?: string | null; + }[] + | null; + employeeOptions?: + | { + value?: string | null; + label?: string | null; + id?: string | null; + }[] + | null; + eligibility?: { + allowedEmployeeValues?: string | null; + requiredBayernValue?: string | null; + eyebrow?: string | null; + heading?: string | null; + employeesLabel?: string | null; + bayernLabel?: string | null; + ownerLabel?: string | null; + ineligibleHeading?: string | null; + ineligibleBody?: string | null; + ineligibleContactPrefix?: string | null; + ineligibleContactEmail?: string | null; + }; + selfContact?: { + eyebrow?: string | null; + heading?: string | null; + companyLabel?: string | null; + companyPlaceholder?: string | null; + nameLabel?: string | null; + namePlaceholder?: string | null; + emailLabel?: string | null; + emailPlaceholder?: string | null; + phoneLabel?: string | null; + phonePlaceholder?: string | null; + footnote?: string | null; + }; + selfSummary?: { + eyebrow?: string | null; + heading?: string | null; + companyLabel?: string | null; + employeesLabel?: string | null; + locationLabel?: string | null; + locationPrefix?: string | null; + contactLabel?: string | null; + }; + nominationCompany?: { + eyebrow?: string | null; + heading?: string | null; + companyLabel?: string | null; + companyPlaceholder?: string | null; + industryLabel?: string | null; + industryPlaceholder?: string | null; + locationLabel?: string | null; + locationPlaceholder?: string | null; + }; + nominationContact?: { + eyebrow?: string | null; + heading?: string | null; + nameLabel?: string | null; + namePlaceholder?: string | null; + emailLabel?: string | null; + emailPlaceholder?: string | null; + relationshipLabel?: string | null; + relationshipPlaceholder?: string | null; + footnote?: string | null; + }; + nominationSummary?: { + eyebrow?: string | null; + heading?: string | null; + companyLabel?: string | null; + industryLabel?: string | null; + locationLabel?: string | null; + nominatedByLabel?: string | null; + emptyValue?: string | null; + }; + success?: { + selfHeading?: string | null; + nominationHeading?: string | null; + selfPrefix?: string | null; + selfMiddle?: string | null; + selfSuffix?: string | null; + nominationPrefix?: string | null; + nominationMiddle?: string | null; + nominationSuffix?: string | null; + }; + }; /** * Copy shown when the hero video button is clicked. */ @@ -3232,6 +3391,144 @@ export interface PagesSelect { footnote?: T; footnoteStrong?: T; }; + form?: + | T + | { + stepCompleteLabel?: T; + backLabel?: T; + nextLabel?: T; + submitLabel?: T; + yesLabel?: T; + noLabel?: T; + requiredSuffix?: T; + validation?: + | T + | { + choose?: T; + required?: T; + invalidEmail?: T; + }; + typeStep?: + | T + | { + eyebrow?: T; + heading?: T; + selfTitle?: T; + selfDesc?: T; + nominationTitle?: T; + nominationDesc?: T; + }; + selfSteps?: + | T + | { + label?: T; + icon?: T; + id?: T; + }; + nominationSteps?: + | T + | { + label?: T; + icon?: T; + id?: T; + }; + employeeOptions?: + | T + | { + value?: T; + label?: T; + id?: T; + }; + eligibility?: + | T + | { + allowedEmployeeValues?: T; + requiredBayernValue?: T; + eyebrow?: T; + heading?: T; + employeesLabel?: T; + bayernLabel?: T; + ownerLabel?: T; + ineligibleHeading?: T; + ineligibleBody?: T; + ineligibleContactPrefix?: T; + ineligibleContactEmail?: T; + }; + selfContact?: + | T + | { + eyebrow?: T; + heading?: T; + companyLabel?: T; + companyPlaceholder?: T; + nameLabel?: T; + namePlaceholder?: T; + emailLabel?: T; + emailPlaceholder?: T; + phoneLabel?: T; + phonePlaceholder?: T; + footnote?: T; + }; + selfSummary?: + | T + | { + eyebrow?: T; + heading?: T; + companyLabel?: T; + employeesLabel?: T; + locationLabel?: T; + locationPrefix?: T; + contactLabel?: T; + }; + nominationCompany?: + | T + | { + eyebrow?: T; + heading?: T; + companyLabel?: T; + companyPlaceholder?: T; + industryLabel?: T; + industryPlaceholder?: T; + locationLabel?: T; + locationPlaceholder?: T; + }; + nominationContact?: + | T + | { + eyebrow?: T; + heading?: T; + nameLabel?: T; + namePlaceholder?: T; + emailLabel?: T; + emailPlaceholder?: T; + relationshipLabel?: T; + relationshipPlaceholder?: T; + footnote?: T; + }; + nominationSummary?: + | T + | { + eyebrow?: T; + heading?: T; + companyLabel?: T; + industryLabel?: T; + locationLabel?: T; + nominatedByLabel?: T; + emptyValue?: T; + }; + success?: + | T + | { + selfHeading?: T; + nominationHeading?: T; + selfPrefix?: T; + selfMiddle?: T; + selfSuffix?: T; + nominationPrefix?: T; + nominationMiddle?: T; + nominationSuffix?: T; + }; + }; videoModal?: | T | { diff --git a/src/scripts/preload-home-page-cms.ts b/src/scripts/preload-home-page-cms.ts index adc5a7a..6a4f906 100644 --- a/src/scripts/preload-home-page-cms.ts +++ b/src/scripts/preload-home-page-cms.ts @@ -89,6 +89,7 @@ async function main() { ...applicationContent, awardImage, }, + form: homeContent.form, videoModal: homeContent.videoModal, }, } as never, diff --git a/src/spa/homeContent.ts b/src/spa/homeContent.ts index ff96826..ffc37cf 100644 --- a/src/spa/homeContent.ts +++ b/src/spa/homeContent.ts @@ -1,3 +1,5 @@ +import { participationContent } from '@/spa/participationContent' + export const homeContent = { hero: { backgroundImageFilename: 'gala-saal-overview.jpg', @@ -209,6 +211,7 @@ export const homeContent = { footnote: 'Kostenlos und unverbindlich –', footnoteStrong: 'keine Teilnahmegebühr', }, + form: participationContent.form, videoModal: { title: 'Video-Player Platzhalter', description: 'Hier würde das Image-Video des BMP geladen werden.', diff --git a/src/spa/pages/Home.tsx b/src/spa/pages/Home.tsx index 8fbbf2a..d3b59be 100644 --- a/src/spa/pages/Home.tsx +++ b/src/spa/pages/Home.tsx @@ -116,6 +116,7 @@ const Home: React.FC = () => { const winnersSection = home.winners || {}; const benefits = home.benefits || {}; const application = home.application || {}; + const form = home.form || {}; const videoModal = home.videoModal || {}; const cmsPreistraeger = useCmsCollection('preistraeger'); const selectedWinners = fallbackArray(winnersSection.featured, []); @@ -551,7 +552,7 @@ const Home: React.FC = () => {
{fallbackText(application.formEyebrow, homeContent.application.formEyebrow)}

{fallbackText(application.formTitle, homeContent.application.formTitle)}

- +