feat: manage participation fallback labels via payload
This commit is contained in:
@@ -109,6 +109,7 @@ export const participationFields: Field[] = [
|
|||||||
text('eyebrow', 'Eyebrow', participationContent.process.eyebrow),
|
text('eyebrow', 'Eyebrow', participationContent.process.eyebrow),
|
||||||
textarea('heading', 'Heading', participationContent.process.heading),
|
textarea('heading', 'Heading', participationContent.process.heading),
|
||||||
textarea('description', 'Intro paragraph', participationContent.process.description),
|
textarea('description', 'Intro paragraph', participationContent.process.description),
|
||||||
|
text('stepPrefix', 'Step label prefix', participationContent.process.stepPrefix),
|
||||||
text('scrollHint', 'Desktop scroll hint', participationContent.process.scrollHint),
|
text('scrollHint', 'Desktop scroll hint', participationContent.process.scrollHint),
|
||||||
text('progressLabel', 'Desktop progress label', participationContent.process.progressLabel),
|
text('progressLabel', 'Desktop progress label', participationContent.process.progressLabel),
|
||||||
{
|
{
|
||||||
@@ -184,6 +185,12 @@ export const participationFields: Field[] = [
|
|||||||
textarea('heading', 'Heading', participationContent.applicationWays.heading),
|
textarea('heading', 'Heading', participationContent.applicationWays.heading),
|
||||||
textarea('description', 'Intro paragraph', participationContent.applicationWays.description),
|
textarea('description', 'Intro paragraph', participationContent.applicationWays.description),
|
||||||
text('recommendedLabel', 'Featured card label', participationContent.applicationWays.recommendedLabel),
|
text('recommendedLabel', 'Featured card label', participationContent.applicationWays.recommendedLabel),
|
||||||
|
ctaGroup(
|
||||||
|
'fallbackCta',
|
||||||
|
'Fallback CTA for path cards',
|
||||||
|
participationContent.applicationWays.fallbackCta.label,
|
||||||
|
participationContent.applicationWays.fallbackCta.url,
|
||||||
|
),
|
||||||
{
|
{
|
||||||
name: 'institutions',
|
name: 'institutions',
|
||||||
label: 'Proposal institutions',
|
label: 'Proposal institutions',
|
||||||
@@ -222,7 +229,7 @@ export const participationFields: Field[] = [
|
|||||||
dbName: 'way_facts',
|
dbName: 'way_facts',
|
||||||
fields: factFields,
|
fields: factFields,
|
||||||
},
|
},
|
||||||
ctaGroup('cta', 'CTA', 'Zum Formular', '#bewerben'),
|
ctaGroup('cta', 'CTA', participationContent.applicationWays.fallbackCta.label, participationContent.applicationWays.fallbackCta.url),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -732,6 +732,7 @@ export interface Page {
|
|||||||
eyebrow?: string | null;
|
eyebrow?: string | null;
|
||||||
heading?: string | null;
|
heading?: string | null;
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
|
stepPrefix?: string | null;
|
||||||
scrollHint?: string | null;
|
scrollHint?: string | null;
|
||||||
progressLabel?: string | null;
|
progressLabel?: string | null;
|
||||||
steps?:
|
steps?:
|
||||||
@@ -872,6 +873,10 @@ export interface Page {
|
|||||||
heading?: string | null;
|
heading?: string | null;
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
recommendedLabel?: string | null;
|
recommendedLabel?: string | null;
|
||||||
|
fallbackCta?: {
|
||||||
|
label?: string | null;
|
||||||
|
url?: string | null;
|
||||||
|
};
|
||||||
institutions?:
|
institutions?:
|
||||||
| {
|
| {
|
||||||
text?: string | null;
|
text?: string | null;
|
||||||
@@ -3711,6 +3716,7 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
eyebrow?: T;
|
eyebrow?: T;
|
||||||
heading?: T;
|
heading?: T;
|
||||||
description?: T;
|
description?: T;
|
||||||
|
stepPrefix?: T;
|
||||||
scrollHint?: T;
|
scrollHint?: T;
|
||||||
progressLabel?: T;
|
progressLabel?: T;
|
||||||
steps?:
|
steps?:
|
||||||
@@ -3796,6 +3802,12 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
heading?: T;
|
heading?: T;
|
||||||
description?: T;
|
description?: T;
|
||||||
recommendedLabel?: T;
|
recommendedLabel?: T;
|
||||||
|
fallbackCta?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
label?: T;
|
||||||
|
url?: T;
|
||||||
|
};
|
||||||
institutions?:
|
institutions?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export default function WegZurAuszeichnungSection({ content }: { content?: Proce
|
|||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const section = { ...participationContent.process, ...(content || {}) };
|
const section = { ...participationContent.process, ...(content || {}) };
|
||||||
const steps = fallbackArray(section.steps, participationContent.process.steps);
|
const steps = fallbackArray(section.steps, participationContent.process.steps);
|
||||||
|
const stepPrefix = fallbackText(section.stepPrefix, participationContent.process.stepPrefix);
|
||||||
|
|
||||||
// ── MOBILE: stacked vertical list (no scroll-jack, no horizontal overflow) ──
|
// ── MOBILE: stacked vertical list (no scroll-jack, no horizontal overflow) ──
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
@@ -66,7 +67,7 @@ export default function WegZurAuszeichnungSection({ content }: { content?: Proce
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
|
||||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.18em', textTransform: 'uppercase' }}>Schritt {fallbackText(item.step, '')}</span>
|
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.18em', textTransform: 'uppercase' }}>{stepPrefix} {fallbackText(item.step, '')}</span>
|
||||||
<span style={{ width: 1, height: 11, background: 'rgba(255,255,255,0.2)' }} />
|
<span style={{ width: 1, height: 11, background: 'rgba(255,255,255,0.2)' }} />
|
||||||
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(255,255,255,0.62)', letterSpacing: '0.06em' }}>{fallbackText(item.date, '')}</span>
|
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(255,255,255,0.62)', letterSpacing: '0.06em' }}>{fallbackText(item.date, '')}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -160,7 +161,7 @@ export default function WegZurAuszeichnungSection({ content }: { content?: Proce
|
|||||||
<div>
|
<div>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 24 }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 24 }}>
|
||||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.22em', textTransform: 'uppercase' }}>
|
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.22em', textTransform: 'uppercase' }}>
|
||||||
Schritt {fallbackText(item.step, '')}
|
{stepPrefix} {fallbackText(item.step, '')}
|
||||||
</span>
|
</span>
|
||||||
<span style={{ width: 1, height: 12, background: 'rgba(255,255,255,0.2)' }} />
|
<span style={{ width: 1, height: 12, background: 'rgba(255,255,255,0.2)' }} />
|
||||||
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(255,255,255,0.62)', letterSpacing: '0.08em' }}>{fallbackText(item.date, '')}</span>
|
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(255,255,255,0.62)', letterSpacing: '0.08em' }}>{fallbackText(item.date, '')}</span>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const Participation: React.FC = () => {
|
|||||||
{/* ── HERO ─────────────────────────────────────────────────────────────── */}
|
{/* ── HERO ─────────────────────────────────────────────────────────────── */}
|
||||||
<section style={{ position: 'relative', minHeight: '65vh', display: 'flex', alignItems: 'flex-end', overflow: 'hidden', background: NAVY }}>
|
<section style={{ position: 'relative', minHeight: '65vh', display: 'flex', alignItems: 'flex-end', overflow: 'hidden', background: NAVY }}>
|
||||||
<Image unoptimized
|
<Image unoptimized
|
||||||
src={mediaUrl(hero.backgroundImage, '/images/preisuebergabe.jpg')}
|
src={mediaUrl(hero.backgroundImage, `/images/${participationContent.hero.backgroundImageFilename}`)}
|
||||||
alt={mediaAlt(hero.backgroundImage, fallbackText(hero.imageAlt, participationContent.hero.imageAlt))}
|
alt={mediaAlt(hero.backgroundImage, fallbackText(hero.imageAlt, participationContent.hero.imageAlt))}
|
||||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
|
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
|
||||||
/>
|
/>
|
||||||
@@ -183,7 +183,7 @@ const Participation: React.FC = () => {
|
|||||||
{/* Left – full-bleed image with gradient blend into navy on the right (+ heading on mobile) */}
|
{/* Left – full-bleed image with gradient blend into navy on the right (+ heading on mobile) */}
|
||||||
<div style={{ position: 'relative', overflow: 'hidden', minHeight: isMobile ? 280 : undefined }}>
|
<div style={{ position: 'relative', overflow: 'hidden', minHeight: isMobile ? 280 : undefined }}>
|
||||||
<Image unoptimized
|
<Image unoptimized
|
||||||
src={mediaUrl(evaluation.image, '/images/buehne-gewinner.jpg')}
|
src={mediaUrl(evaluation.image, `/images/${participationContent.evaluation.imageFilename}`)}
|
||||||
alt={mediaAlt(evaluation.image, fallbackText(evaluation.imageAlt, participationContent.evaluation.imageAlt))}
|
alt={mediaAlt(evaluation.image, fallbackText(evaluation.imageAlt, participationContent.evaluation.imageAlt))}
|
||||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center', display: 'block' }}
|
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center', display: 'block' }}
|
||||||
/>
|
/>
|
||||||
@@ -329,7 +329,7 @@ const Participation: React.FC = () => {
|
|||||||
|
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<div style={{ height: 220, position: 'relative', overflow: 'hidden', flexShrink: 0, zIndex: 1 }}>
|
<div style={{ height: 220, position: 'relative', overflow: 'hidden', flexShrink: 0, zIndex: 1 }}>
|
||||||
<Image unoptimized src={mediaUrl(applicationForm.image, '/images/preistraeger-jubel.jpg')} alt={mediaAlt(applicationForm.image, fallbackText(applicationForm.imageAlt, participationContent.applicationForm.imageAlt))} style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%', filter: 'sepia(0.18) brightness(0.92)' }} />
|
<Image unoptimized src={mediaUrl(applicationForm.image, `/images/${participationContent.applicationForm.imageFilename}`)} alt={mediaAlt(applicationForm.image, fallbackText(applicationForm.imageAlt, participationContent.applicationForm.imageAlt))} style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%', filter: 'sepia(0.18) brightness(0.92)' }} />
|
||||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(168,120,0,0.1) 0%, rgba(168,120,0,0.25) 50%, rgba(168,120,0,0.92) 88%, #A87800 100%)' }} />
|
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(168,120,0,0.1) 0%, rgba(168,120,0,0.25) 50%, rgba(168,120,0,0.92) 88%, #A87800 100%)' }} />
|
||||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'rgba(17,29,85,0.35)' }} />
|
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'rgba(17,29,85,0.35)' }} />
|
||||||
<div style={{ position: 'absolute', bottom: 16, left: 40, display: 'flex', alignItems: 'center', gap: 8 }}>
|
<div style={{ position: 'absolute', bottom: 16, left: 40, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||||
@@ -430,6 +430,7 @@ function BewerbungswegeSection({ content }: { content?: ApplicationWaysContent }
|
|||||||
const section = { ...participationContent.applicationWays, ...(content || {}) };
|
const section = { ...participationContent.applicationWays, ...(content || {}) };
|
||||||
const institutions = fallbackArray(section.institutions, participationContent.applicationWays.institutions);
|
const institutions = fallbackArray(section.institutions, participationContent.applicationWays.institutions);
|
||||||
const ways = fallbackArray(section.ways, participationContent.applicationWays.ways);
|
const ways = fallbackArray(section.ways, participationContent.applicationWays.ways);
|
||||||
|
const fallbackCta = { ...participationContent.applicationWays.fallbackCta, ...(section.fallbackCta || {}) };
|
||||||
return (
|
return (
|
||||||
<section style={{ background: CREAM, position: 'relative', overflow: 'hidden', isolation: 'isolate' }}>
|
<section style={{ background: CREAM, position: 'relative', overflow: 'hidden', isolation: 'isolate' }}>
|
||||||
<MunichSkylineBg />
|
<MunichSkylineBg />
|
||||||
@@ -488,7 +489,7 @@ function BewerbungswegeSection({ content }: { content?: ApplicationWaysContent }
|
|||||||
</div>
|
</div>
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<div style={{ padding: '18px 22px 22px' }}>
|
<div style={{ padding: '18px 22px 22px' }}>
|
||||||
<a href={fallbackText(w.cta?.url, '#bewerben')} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, minHeight: 52, background: GOLD, color: '#101828', fontFamily: FF, fontSize: 14, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', textDecoration: 'none', borderRadius: 10 }}>{fallbackText(w.cta?.label, 'Zum Formular')} <ArrowRight size={14} /></a>
|
<a href={fallbackText(w.cta?.url, fallbackCta.url)} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, minHeight: 52, background: GOLD, color: '#101828', fontFamily: FF, fontSize: 14, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', textDecoration: 'none', borderRadius: 10 }}>{fallbackText(w.cta?.label, fallbackCta.label)} <ArrowRight size={14} /></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -532,12 +533,12 @@ function BewerbungswegeSection({ content }: { content?: ApplicationWaysContent }
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={fallbackText(w.cta?.url, '#bewerben')}
|
href={fallbackText(w.cta?.url, fallbackCta.url)}
|
||||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '14px 24px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 36, alignSelf: 'flex-start', transition: 'opacity 0.15s' }}
|
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '14px 24px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 36, alignSelf: 'flex-start', transition: 'opacity 0.15s' }}
|
||||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||||
>
|
>
|
||||||
{fallbackText(w.cta?.label, 'Zum Formular')} <ArrowRight size={13} />
|
{fallbackText(w.cta?.label, fallbackCta.label)} <ArrowRight size={13} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export const participationContent = {
|
|||||||
heading: 'IHR WEG ZUM\nPREIS.',
|
heading: 'IHR WEG ZUM\nPREIS.',
|
||||||
description:
|
description:
|
||||||
'Von der Einreichung bis zur Gala – vier klar definierte Schritte auf dem Weg zur höchsten Auszeichnung des bayerischen Mittelstands.',
|
'Von der Einreichung bis zur Gala – vier klar definierte Schritte auf dem Weg zur höchsten Auszeichnung des bayerischen Mittelstands.',
|
||||||
|
stepPrefix: 'Schritt',
|
||||||
scrollHint: 'Scrollen zum Erkunden',
|
scrollHint: 'Scrollen zum Erkunden',
|
||||||
progressLabel: '01 / 04',
|
progressLabel: '01 / 04',
|
||||||
steps: [
|
steps: [
|
||||||
@@ -105,6 +106,7 @@ export const participationContent = {
|
|||||||
'Mitglieder des Wirtschaftsbeirates Bayern',
|
'Mitglieder des Wirtschaftsbeirates Bayern',
|
||||||
'Ehemalige Preisträger des Bayerischen Mittelstandspreises',
|
'Ehemalige Preisträger des Bayerischen Mittelstandspreises',
|
||||||
].map((text) => ({ text })),
|
].map((text) => ({ text })),
|
||||||
|
fallbackCta: { label: 'Zum Formular', url: '#bewerben' },
|
||||||
ways: [
|
ways: [
|
||||||
{
|
{
|
||||||
label: 'Weg 01',
|
label: 'Weg 01',
|
||||||
|
|||||||
Reference in New Issue
Block a user