feat: manage preistraeger fallback media via payload

This commit is contained in:
syntaxbullet
2026-06-22 12:40:37 +02:00
parent 79a9075f3a
commit 4a751317b0
10 changed files with 82 additions and 18 deletions

View File

@@ -17,18 +17,19 @@ const BG_ALT = '#E4E2E3';
type PreistraegerIndexCms = Partial<typeof preistraegerIndexContent> & {
hero?: Partial<typeof preistraegerIndexContent.hero> & { image?: unknown }
card?: Partial<typeof preistraegerIndexContent.card> & { fallbackImage?: unknown }
}
const fallbackText = (value: unknown, fallback: string) => typeof value === 'string' && value.length > 0 ? value : fallback;
const normalizeWinner = (doc: CmsRouteDoc): Winner => ({
const normalizeWinner = (doc: CmsRouteDoc, fallbackImage: string): Winner => ({
id: String(doc.id),
slug: String(doc.slug || ''),
name: String(doc.title || 'Preisträger'),
category: String(doc.category || 'Preisträger'),
year: Number(doc.year || new Date().getFullYear()),
type: String(doc.awardType || 'Auszeichnung'),
img: docImageUrl(doc, '/images/gala-saal-overview.jpg'),
img: docImageUrl(doc, fallbackImage),
shortDesc: String(doc.shortDesc || doc.description || doc.meta?.description || ''),
longDesc: String(doc.longDesc || doc.description || doc.meta?.description || ''),
quote: String(doc.quote || ''),
@@ -52,12 +53,16 @@ export default function Preistraeger() {
const filters = { ...preistraegerIndexContent.filters, ...(cms.filters || {}) };
const count = { ...preistraegerIndexContent.count, ...(cms.count || {}) };
const empty = { ...preistraegerIndexContent.empty, ...(cms.empty || {}) };
const card = { ...preistraegerIndexContent.card, ...(cms.card || {}) };
const card = useMemo(() => ({ ...preistraegerIndexContent.card, ...(cms.card || {}) }), [cms.card]);
const cta = { ...preistraegerIndexContent.cta, ...(cms.cta || {}) };
const cardFallbackImage = useMemo(
() => mediaUrl(card.fallbackImage, `/images/${preistraegerIndexContent.card.fallbackImageFilename}`),
[card],
);
const winners = useMemo(() => {
if (cmsPreistraeger.length) return cmsPreistraeger.map(normalizeWinner).filter((winner) => winner.slug);
if (cmsPreistraeger.length) return cmsPreistraeger.map((doc) => normalizeWinner(doc, cardFallbackImage)).filter((winner) => winner.slug);
return WINNERS;
}, [cmsPreistraeger]);
}, [cardFallbackImage, cmsPreistraeger]);
const years = useMemo(() => [...new Set(winners.map((winner) => winner.year))].sort((a, b) => b - a), [winners]);
const categories = useMemo(() => [...new Set(winners.map((winner) => winner.category))].sort((a, b) => a.localeCompare(b, 'de')), [winners]);
const [activeYear, setActiveYear] = useState<number | undefined>(undefined);