feat: manage about highlight fallback copy via payload
This commit is contained in:
@@ -134,6 +134,16 @@ export const aboutFields: Field[] = [
|
|||||||
textarea('heading', 'Heading', aboutContent.highlights.heading),
|
textarea('heading', 'Heading', aboutContent.highlights.heading),
|
||||||
ctaGroup('cta', 'CTA', aboutContent.highlights.cta.label, aboutContent.highlights.cta.url),
|
ctaGroup('cta', 'CTA', aboutContent.highlights.cta.label, aboutContent.highlights.cta.url),
|
||||||
text('hoverLabel', 'Card hover label', aboutContent.highlights.hoverLabel),
|
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',
|
name: 'year',
|
||||||
label: 'Fallback winner year',
|
label: 'Fallback winner year',
|
||||||
|
|||||||
@@ -1230,6 +1230,11 @@ export interface Page {
|
|||||||
url?: string | null;
|
url?: string | null;
|
||||||
};
|
};
|
||||||
hoverLabel?: string | null;
|
hoverLabel?: string | null;
|
||||||
|
fallbackWinner?: {
|
||||||
|
name?: string | null;
|
||||||
|
category?: string | null;
|
||||||
|
awardType?: string | null;
|
||||||
|
};
|
||||||
year?: number | null;
|
year?: number | null;
|
||||||
/**
|
/**
|
||||||
* Choose up to 8 Preisträger to show. If empty, the frontend falls back to winners from the selected year.
|
* Choose up to 8 Preisträger to show. If empty, the frontend falls back to winners from the selected year.
|
||||||
@@ -4169,6 +4174,13 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
url?: T;
|
url?: T;
|
||||||
};
|
};
|
||||||
hoverLabel?: T;
|
hoverLabel?: T;
|
||||||
|
fallbackWinner?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
name?: T;
|
||||||
|
category?: T;
|
||||||
|
awardType?: T;
|
||||||
|
};
|
||||||
year?: T;
|
year?: T;
|
||||||
selectedWinners?: T;
|
selectedWinners?: T;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ export const aboutContent = {
|
|||||||
cta: { label: 'Alle Preisträger', url: '/preistraeger' },
|
cta: { label: 'Alle Preisträger', url: '/preistraeger' },
|
||||||
hoverLabel: 'Detail →',
|
hoverLabel: 'Detail →',
|
||||||
year: 2025,
|
year: 2025,
|
||||||
|
fallbackWinner: {
|
||||||
|
name: 'Preisträger',
|
||||||
|
category: 'Preisträger',
|
||||||
|
awardType: 'Auszeichnung',
|
||||||
|
},
|
||||||
selectedWinners: [],
|
selectedWinners: [],
|
||||||
},
|
},
|
||||||
testimonials: testimonialsContent,
|
testimonials: testimonialsContent,
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ type AboutCms = Partial<typeof aboutContent> & {
|
|||||||
hero?: Partial<typeof aboutContent.hero> & { backgroundImage?: unknown }
|
hero?: Partial<typeof aboutContent.hero> & { backgroundImage?: unknown }
|
||||||
prize?: Partial<typeof aboutContent.prize> & { image?: unknown }
|
prize?: Partial<typeof aboutContent.prize> & { image?: unknown }
|
||||||
mittelstand?: Partial<typeof aboutContent.mittelstand> & { image?: unknown }
|
mittelstand?: Partial<typeof aboutContent.mittelstand> & { image?: unknown }
|
||||||
highlights?: Partial<typeof aboutContent.highlights> & { fallbackImage?: unknown; selectedWinners?: unknown[] | null }
|
highlights?: Partial<typeof aboutContent.highlights> & {
|
||||||
|
fallbackImage?: unknown
|
||||||
|
fallbackWinner?: Partial<typeof aboutContent.highlights.fallbackWinner>
|
||||||
|
selectedWinners?: unknown[] | null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextRow = { text?: string | null }
|
type TextRow = { text?: string | null }
|
||||||
@@ -63,15 +67,19 @@ function HighlightedText({ text, highlight }: { text: string; highlight: string
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizeWinner = (doc: CmsRouteDoc | undefined, fallbackImage: string): Winner | undefined => {
|
const normalizeWinner = (
|
||||||
|
doc: CmsRouteDoc | undefined,
|
||||||
|
fallbackImage: string,
|
||||||
|
fallbackWinner: typeof aboutContent.highlights.fallbackWinner,
|
||||||
|
): Winner | undefined => {
|
||||||
if (!doc) return undefined
|
if (!doc) return undefined
|
||||||
return {
|
return {
|
||||||
id: String(doc.id),
|
id: String(doc.id),
|
||||||
slug: String(doc.slug || ''),
|
slug: String(doc.slug || ''),
|
||||||
name: String(doc.title || 'Preisträger'),
|
name: String(doc.title || fallbackWinner.name),
|
||||||
category: String(doc.category || 'Preisträger'),
|
category: String(doc.category || fallbackWinner.category),
|
||||||
year: Number(doc.year || aboutContent.highlights.year),
|
year: Number(doc.year || aboutContent.highlights.year),
|
||||||
type: String(doc.awardType || 'Auszeichnung'),
|
type: String(doc.awardType || fallbackWinner.awardType),
|
||||||
img: mediaUrl(doc.image, fallbackImage),
|
img: mediaUrl(doc.image, fallbackImage),
|
||||||
shortDesc: String(doc.shortDesc || doc.description || doc.meta?.description || ''),
|
shortDesc: String(doc.shortDesc || doc.description || doc.meta?.description || ''),
|
||||||
longDesc: String(doc.longDesc || doc.description || doc.meta?.description || ''),
|
longDesc: String(doc.longDesc || doc.description || doc.meta?.description || ''),
|
||||||
@@ -85,10 +93,15 @@ const normalizeWinner = (doc: CmsRouteDoc | undefined, fallbackImage: string): W
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const winnerFromRelationship = (entry: unknown, allDocs: CmsRouteDoc[], fallbackImage: string) => {
|
const winnerFromRelationship = (
|
||||||
if (entry && typeof entry === 'object') return normalizeWinner(entry as CmsRouteDoc, fallbackImage)
|
entry: unknown,
|
||||||
|
allDocs: CmsRouteDoc[],
|
||||||
|
fallbackImage: string,
|
||||||
|
fallbackWinner: typeof aboutContent.highlights.fallbackWinner,
|
||||||
|
) => {
|
||||||
|
if (entry && typeof entry === 'object') return normalizeWinner(entry as CmsRouteDoc, fallbackImage, fallbackWinner)
|
||||||
const doc = allDocs.find((item) => String(item.id) === String(entry))
|
const doc = allDocs.find((item) => String(item.id) === String(entry))
|
||||||
return normalizeWinner(doc, fallbackImage)
|
return normalizeWinner(doc, fallbackImage, fallbackWinner)
|
||||||
}
|
}
|
||||||
|
|
||||||
const About: React.FC = () => {
|
const About: React.FC = () => {
|
||||||
@@ -108,10 +121,14 @@ const About: React.FC = () => {
|
|||||||
highlights.fallbackImage,
|
highlights.fallbackImage,
|
||||||
`/images/${aboutContent.highlights.fallbackImageFilename}`,
|
`/images/${aboutContent.highlights.fallbackImageFilename}`,
|
||||||
)
|
)
|
||||||
|
const highlightFallbackWinner = useMemo(
|
||||||
|
() => ({ ...aboutContent.highlights.fallbackWinner, ...(highlights.fallbackWinner || {}) }),
|
||||||
|
[highlights],
|
||||||
|
)
|
||||||
|
|
||||||
const highlightWinners = useMemo(() => {
|
const highlightWinners = useMemo(() => {
|
||||||
const selected = fallbackArray<unknown>(highlights.selectedWinners, [])
|
const selected = fallbackArray<unknown>(highlights.selectedWinners, [])
|
||||||
.map((entry) => winnerFromRelationship(entry, cmsWinners, highlightFallbackImage))
|
.map((entry) => winnerFromRelationship(entry, cmsWinners, highlightFallbackImage, highlightFallbackWinner))
|
||||||
.filter((winner): winner is Winner => Boolean(winner))
|
.filter((winner): winner is Winner => Boolean(winner))
|
||||||
|
|
||||||
if (selected.length) return selected.slice(0, 8)
|
if (selected.length) return selected.slice(0, 8)
|
||||||
@@ -120,12 +137,12 @@ const About: React.FC = () => {
|
|||||||
Boolean(winner) && winner?.year === Number(highlights.year || aboutContent.highlights.year)
|
Boolean(winner) && winner?.year === Number(highlights.year || aboutContent.highlights.year)
|
||||||
|
|
||||||
const cmsByYear = cmsWinners
|
const cmsByYear = cmsWinners
|
||||||
.map((winner) => normalizeWinner(winner, highlightFallbackImage))
|
.map((winner) => normalizeWinner(winner, highlightFallbackImage, highlightFallbackWinner))
|
||||||
.filter(isWinnerFromYear)
|
.filter(isWinnerFromYear)
|
||||||
.slice(0, 8)
|
.slice(0, 8)
|
||||||
|
|
||||||
return cmsByYear.length ? cmsByYear : FALLBACK_HIGHLIGHTS
|
return cmsByYear.length ? cmsByYear : FALLBACK_HIGHLIGHTS
|
||||||
}, [cmsWinners, highlightFallbackImage, highlights])
|
}, [cmsWinners, highlightFallbackImage, highlightFallbackWinner, highlights])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="animate-fade-in">
|
<div className="animate-fade-in">
|
||||||
|
|||||||
Reference in New Issue
Block a user