feat: manage preistraeger fallback copy via payload
This commit is contained in:
@@ -100,6 +100,18 @@ export const preistraegerIndexFields: Field[] = [
|
|||||||
fields: [
|
fields: [
|
||||||
uploadField('fallbackImage', 'Fallback card image', `Current frontend fallback image: /images/${preistraegerIndexContent.card.fallbackImageFilename}`),
|
uploadField('fallbackImage', 'Fallback card image', `Current frontend fallback image: /images/${preistraegerIndexContent.card.fallbackImageFilename}`),
|
||||||
text('hoverLabel', 'Hover label', preistraegerIndexContent.card.hoverLabel),
|
text('hoverLabel', 'Hover label', preistraegerIndexContent.card.hoverLabel),
|
||||||
|
{
|
||||||
|
name: 'fallbackWinner',
|
||||||
|
label: 'Missing winner field fallbacks',
|
||||||
|
type: 'group',
|
||||||
|
fields: [
|
||||||
|
text('name', 'Name', preistraegerIndexContent.card.fallbackWinner.name),
|
||||||
|
text('category', 'Category', preistraegerIndexContent.card.fallbackWinner.category),
|
||||||
|
text('awardType', 'Award type', preistraegerIndexContent.card.fallbackWinner.awardType),
|
||||||
|
text('location', 'Location', preistraegerIndexContent.card.fallbackWinner.location),
|
||||||
|
text('industry', 'Industry', preistraegerIndexContent.card.fallbackWinner.industry),
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -138,6 +138,22 @@ export const Preistraeger: CollectionConfig = {
|
|||||||
{ name: 'label', type: 'text', label: 'Label', defaultValue: preistraegerDetailContent.breadcrumb.label },
|
{ name: 'label', type: 'text', label: 'Label', defaultValue: preistraegerDetailContent.breadcrumb.label },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'fallbackWinner',
|
||||||
|
label: 'Missing winner field fallbacks',
|
||||||
|
type: 'group',
|
||||||
|
fields: [
|
||||||
|
{ name: 'name', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.name },
|
||||||
|
{ name: 'category', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.category },
|
||||||
|
{ name: 'awardType', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.awardType },
|
||||||
|
{ name: 'longDesc', type: 'textarea', defaultValue: preistraegerDetailContent.fallbackWinner.longDesc },
|
||||||
|
{ name: 'quote', type: 'textarea', defaultValue: preistraegerDetailContent.fallbackWinner.quote },
|
||||||
|
{ name: 'quotePerson', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.quotePerson },
|
||||||
|
{ name: 'quoteRole', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.quoteRole },
|
||||||
|
{ name: 'location', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.location },
|
||||||
|
{ name: 'industry', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.industry },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'sections',
|
name: 'sections',
|
||||||
label: 'Section copy',
|
label: 'Section copy',
|
||||||
|
|||||||
@@ -1463,6 +1463,13 @@ export interface Page {
|
|||||||
*/
|
*/
|
||||||
fallbackImage?: (number | null) | Media;
|
fallbackImage?: (number | null) | Media;
|
||||||
hoverLabel?: string | null;
|
hoverLabel?: string | null;
|
||||||
|
fallbackWinner?: {
|
||||||
|
name?: string | null;
|
||||||
|
category?: string | null;
|
||||||
|
awardType?: string | null;
|
||||||
|
location?: string | null;
|
||||||
|
industry?: string | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Bottom application and membership CTA.
|
* Bottom application and membership CTA.
|
||||||
@@ -2782,6 +2789,17 @@ export interface Preistraeger {
|
|||||||
url?: string | null;
|
url?: string | null;
|
||||||
label?: string | null;
|
label?: string | null;
|
||||||
};
|
};
|
||||||
|
fallbackWinner?: {
|
||||||
|
name?: string | null;
|
||||||
|
category?: string | null;
|
||||||
|
awardType?: string | null;
|
||||||
|
longDesc?: string | null;
|
||||||
|
quote?: string | null;
|
||||||
|
quotePerson?: string | null;
|
||||||
|
quoteRole?: string | null;
|
||||||
|
location?: string | null;
|
||||||
|
industry?: string | null;
|
||||||
|
};
|
||||||
sections?: {
|
sections?: {
|
||||||
companyHeading?: string | null;
|
companyHeading?: string | null;
|
||||||
juryHeading?: string | null;
|
juryHeading?: string | null;
|
||||||
@@ -4336,6 +4354,15 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
| {
|
| {
|
||||||
fallbackImage?: T;
|
fallbackImage?: T;
|
||||||
hoverLabel?: T;
|
hoverLabel?: T;
|
||||||
|
fallbackWinner?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
name?: T;
|
||||||
|
category?: T;
|
||||||
|
awardType?: T;
|
||||||
|
location?: T;
|
||||||
|
industry?: T;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
cta?:
|
cta?:
|
||||||
| T
|
| T
|
||||||
@@ -5243,6 +5270,19 @@ export interface PreistraegerSelect<T extends boolean = true> {
|
|||||||
url?: T;
|
url?: T;
|
||||||
label?: T;
|
label?: T;
|
||||||
};
|
};
|
||||||
|
fallbackWinner?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
name?: T;
|
||||||
|
category?: T;
|
||||||
|
awardType?: T;
|
||||||
|
longDesc?: T;
|
||||||
|
quote?: T;
|
||||||
|
quotePerson?: T;
|
||||||
|
quoteRole?: T;
|
||||||
|
location?: T;
|
||||||
|
industry?: T;
|
||||||
|
};
|
||||||
sections?:
|
sections?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -22,21 +22,25 @@ type PreistraegerIndexCms = Partial<typeof preistraegerIndexContent> & {
|
|||||||
|
|
||||||
const fallbackText = (value: unknown, fallback: string) => typeof value === 'string' && value.length > 0 ? value : fallback;
|
const fallbackText = (value: unknown, fallback: string) => typeof value === 'string' && value.length > 0 ? value : fallback;
|
||||||
|
|
||||||
const normalizeWinner = (doc: CmsRouteDoc, fallbackImage: string): Winner => ({
|
const normalizeWinner = (
|
||||||
|
doc: CmsRouteDoc,
|
||||||
|
fallbackImage: string,
|
||||||
|
fallbackWinner: typeof preistraegerIndexContent.card.fallbackWinner,
|
||||||
|
): Winner => ({
|
||||||
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 || preistraegerIndexContent.card.fallbackWinner.name),
|
||||||
category: String(doc.category || 'Preisträger'),
|
category: String(doc.category || fallbackWinner.category || preistraegerIndexContent.card.fallbackWinner.category),
|
||||||
year: Number(doc.year || new Date().getFullYear()),
|
year: Number(doc.year || new Date().getFullYear()),
|
||||||
type: String(doc.awardType || 'Auszeichnung'),
|
type: String(doc.awardType || fallbackWinner.awardType || preistraegerIndexContent.card.fallbackWinner.awardType),
|
||||||
img: docImageUrl(doc, fallbackImage),
|
img: docImageUrl(doc, 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 || ''),
|
||||||
quote: String(doc.quote || ''),
|
quote: String(doc.quote || ''),
|
||||||
quotePerson: String(doc.quotePerson || ''),
|
quotePerson: String(doc.quotePerson || ''),
|
||||||
quoteRole: String(doc.quoteRole || ''),
|
quoteRole: String(doc.quoteRole || ''),
|
||||||
location: String(doc.location || 'Bayern'),
|
location: String(doc.location || fallbackWinner.location || preistraegerIndexContent.card.fallbackWinner.location),
|
||||||
industry: String(doc.industry || 'Mittelstand'),
|
industry: String(doc.industry || fallbackWinner.industry || preistraegerIndexContent.card.fallbackWinner.industry),
|
||||||
website: String(doc.website || '#'),
|
website: String(doc.website || '#'),
|
||||||
hasMedia: Boolean(doc.hasMedia),
|
hasMedia: Boolean(doc.hasMedia),
|
||||||
});
|
});
|
||||||
@@ -60,9 +64,10 @@ export default function Preistraeger() {
|
|||||||
[card],
|
[card],
|
||||||
);
|
);
|
||||||
const winners = useMemo(() => {
|
const winners = useMemo(() => {
|
||||||
if (cmsPreistraeger.length) return cmsPreistraeger.map((doc) => normalizeWinner(doc, cardFallbackImage)).filter((winner) => winner.slug);
|
const fallbackWinner = card.fallbackWinner || preistraegerIndexContent.card.fallbackWinner;
|
||||||
|
if (cmsPreistraeger.length) return cmsPreistraeger.map((doc) => normalizeWinner(doc, cardFallbackImage, fallbackWinner)).filter((winner) => winner.slug);
|
||||||
return WINNERS;
|
return WINNERS;
|
||||||
}, [cardFallbackImage, cmsPreistraeger]);
|
}, [card, cardFallbackImage, cmsPreistraeger]);
|
||||||
const years = useMemo(() => [...new Set(winners.map((winner) => winner.year))].sort((a, b) => b - a), [winners]);
|
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 categories = useMemo(() => [...new Set(winners.map((winner) => winner.category))].sort((a, b) => a.localeCompare(b, 'de')), [winners]);
|
||||||
const [activeYear, setActiveYear] = useState<number | undefined>(undefined);
|
const [activeYear, setActiveYear] = useState<number | undefined>(undefined);
|
||||||
|
|||||||
@@ -31,22 +31,23 @@ export default function PreistraegerDetail() {
|
|||||||
...preistraegerDetailContent,
|
...preistraegerDetailContent,
|
||||||
...((cmsWinner?.detailPage || {}) as PreistraegerDetailCms),
|
...((cmsWinner?.detailPage || {}) as PreistraegerDetailCms),
|
||||||
} as PreistraegerDetailCms;
|
} as PreistraegerDetailCms;
|
||||||
|
const fallbackWinner = cmsDetail.fallbackWinner || preistraegerDetailContent.fallbackWinner;
|
||||||
const winnerFallbackImage = mediaUrl(cmsDetail.fallbackImage, `/images/${preistraegerDetailContent.fallbackImageFilename}`);
|
const winnerFallbackImage = mediaUrl(cmsDetail.fallbackImage, `/images/${preistraegerDetailContent.fallbackImageFilename}`);
|
||||||
const winner = cmsWinner ? {
|
const winner = cmsWinner ? {
|
||||||
id: String(cmsWinner.id),
|
id: String(cmsWinner.id),
|
||||||
slug: String(cmsWinner.slug || slug),
|
slug: String(cmsWinner.slug || slug),
|
||||||
name: String(cmsWinner.title || 'Preisträger'),
|
name: String(cmsWinner.title || fallbackWinner.name || preistraegerDetailContent.fallbackWinner.name),
|
||||||
category: String(cmsWinner.category || 'Preisträger'),
|
category: String(cmsWinner.category || fallbackWinner.category || preistraegerDetailContent.fallbackWinner.category),
|
||||||
year: Number(cmsWinner.year || new Date().getFullYear()),
|
year: Number(cmsWinner.year || new Date().getFullYear()),
|
||||||
type: String(cmsWinner.awardType || 'Auszeichnung'),
|
type: String(cmsWinner.awardType || fallbackWinner.awardType || preistraegerDetailContent.fallbackWinner.awardType),
|
||||||
img: docImageUrl(cmsWinner, winnerFallbackImage),
|
img: docImageUrl(cmsWinner, winnerFallbackImage),
|
||||||
shortDesc: String(cmsWinner.shortDesc || cmsWinner.description || cmsWinner.meta?.description || ''),
|
shortDesc: String(cmsWinner.shortDesc || cmsWinner.description || cmsWinner.meta?.description || ''),
|
||||||
longDesc: String(cmsWinner.longDesc || cmsWinner.description || cmsWinner.meta?.description || 'Dieser Preisträger wird aus Payload CMS geladen.'),
|
longDesc: String(cmsWinner.longDesc || cmsWinner.description || cmsWinner.meta?.description || fallbackWinner.longDesc || preistraegerDetailContent.fallbackWinner.longDesc),
|
||||||
quote: String(cmsWinner.quote || 'Diese Erfolgsgeschichte wird aktuell in Payload CMS gepflegt.'),
|
quote: String(cmsWinner.quote || fallbackWinner.quote || preistraegerDetailContent.fallbackWinner.quote),
|
||||||
quotePerson: String(cmsWinner.quotePerson || cmsWinner.title || 'BMP'),
|
quotePerson: String(cmsWinner.quotePerson || cmsWinner.title || fallbackWinner.quotePerson || preistraegerDetailContent.fallbackWinner.quotePerson),
|
||||||
quoteRole: String(cmsWinner.quoteRole || 'Preisträger'),
|
quoteRole: String(cmsWinner.quoteRole || fallbackWinner.quoteRole || preistraegerDetailContent.fallbackWinner.quoteRole),
|
||||||
location: String(cmsWinner.location || 'Bayern'),
|
location: String(cmsWinner.location || fallbackWinner.location || preistraegerDetailContent.fallbackWinner.location),
|
||||||
industry: String(cmsWinner.industry || 'Mittelstand'),
|
industry: String(cmsWinner.industry || fallbackWinner.industry || preistraegerDetailContent.fallbackWinner.industry),
|
||||||
website: String(cmsWinner.website || '#'),
|
website: String(cmsWinner.website || '#'),
|
||||||
hasMedia: Boolean(cmsWinner.hasMedia),
|
hasMedia: Boolean(cmsWinner.hasMedia),
|
||||||
detailPage: (cmsWinner.detailPage || {}) as PreistraegerDetailCms,
|
detailPage: (cmsWinner.detailPage || {}) as PreistraegerDetailCms,
|
||||||
|
|||||||
@@ -5,6 +5,17 @@ export const preistraegerDetailContent = {
|
|||||||
url: '/preistraeger',
|
url: '/preistraeger',
|
||||||
label: 'Preisträger:innen',
|
label: 'Preisträger:innen',
|
||||||
},
|
},
|
||||||
|
fallbackWinner: {
|
||||||
|
name: 'Preisträger',
|
||||||
|
category: 'Preisträger',
|
||||||
|
awardType: 'Auszeichnung',
|
||||||
|
longDesc: 'Dieser Preisträger wird aus Payload CMS geladen.',
|
||||||
|
quote: 'Diese Erfolgsgeschichte wird aktuell in Payload CMS gepflegt.',
|
||||||
|
quotePerson: 'BMP',
|
||||||
|
quoteRole: 'Preisträger',
|
||||||
|
location: 'Bayern',
|
||||||
|
industry: 'Mittelstand',
|
||||||
|
},
|
||||||
sections: {
|
sections: {
|
||||||
companyHeading: 'Über das Unternehmen',
|
companyHeading: 'Über das Unternehmen',
|
||||||
juryHeading: 'Warum ausgezeichnet?',
|
juryHeading: 'Warum ausgezeichnet?',
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ export const preistraegerIndexContent = {
|
|||||||
card: {
|
card: {
|
||||||
fallbackImageFilename: 'gala-saal-overview.jpg',
|
fallbackImageFilename: 'gala-saal-overview.jpg',
|
||||||
hoverLabel: 'Mehr erfahren',
|
hoverLabel: 'Mehr erfahren',
|
||||||
|
fallbackWinner: {
|
||||||
|
name: 'Preisträger',
|
||||||
|
category: 'Preisträger',
|
||||||
|
awardType: 'Auszeichnung',
|
||||||
|
location: 'Bayern',
|
||||||
|
industry: 'Mittelstand',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
cta: {
|
cta: {
|
||||||
text: 'Werden Sie der nächste Preisträger.',
|
text: 'Werden Sie der nächste Preisträger.',
|
||||||
|
|||||||
Reference in New Issue
Block a user