feat: implement home winners selection logic with fallback handling and add integration tests
This commit is contained in:
26
src/spa/homeWinnerSelection.ts
Normal file
26
src/spa/homeWinnerSelection.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { resolveCmsRelationship, type CmsRouteDoc } from '@/spa/cmsRoute'
|
||||
|
||||
const FALLBACK_YEAR = 2025
|
||||
const FALLBACK_LIMIT = 8
|
||||
|
||||
type FallbackWinner = {
|
||||
id: string | number
|
||||
year?: string | number
|
||||
}
|
||||
|
||||
export function resolveHomeWinners(
|
||||
featured: unknown,
|
||||
cmsWinners: CmsRouteDoc[],
|
||||
fallbackWinners: FallbackWinner[],
|
||||
) {
|
||||
const selectedWinners = Array.isArray(featured) ? featured : []
|
||||
const selectedWinnerDocs = selectedWinners
|
||||
.map((selected) => resolveCmsRelationship(selected, cmsWinners))
|
||||
.filter((winner): winner is CmsRouteDoc => Boolean(winner))
|
||||
|
||||
if (selectedWinnerDocs.length) return selectedWinnerDocs
|
||||
|
||||
return (cmsWinners.length ? cmsWinners : fallbackWinners)
|
||||
.filter((winner) => Number(winner.year) === FALLBACK_YEAR)
|
||||
.slice(0, FALLBACK_LIMIT)
|
||||
}
|
||||
@@ -11,9 +11,10 @@ import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
import Image from '@/spa/components/ui/UnoptimizedImage'
|
||||
import type { SpaApplicationPhaseData, SpaApplicationPhaseItem } from '@/spa/applicationPhase'
|
||||
import { resolveCmsRelationship, useApplicationPhase, useCmsCollection, useCmsRoute, useNewsletterForm } from '@/spa/cmsRoute'
|
||||
import { useApplicationPhase, useCmsCollection, useCmsRoute, useNewsletterForm } from '@/spa/cmsRoute'
|
||||
import { mediaAlt, mediaUrl } from '@/spa/cmsMediaField'
|
||||
import { homeContent } from '@/spa/homeContent'
|
||||
import { resolveHomeWinners } from '@/spa/homeWinnerSelection'
|
||||
import { netzwerkContent } from '@/spa/netzwerkContent'
|
||||
import { usePreistraegerPlaceholderImage } from '@/spa/preistraegerPlaceholder'
|
||||
import { PartnerLogoMark, type PartnerLogoData } from '@/spa/components/ui/partner-logo'
|
||||
@@ -251,26 +252,12 @@ const Home: React.FC = () => {
|
||||
const newsletterCopy = newsletterFormCopyForPhase(newsletterForm, activeApplicationPhase);
|
||||
const newsletterPhase = newsletterPhaseForApplicationPhase(activeApplicationPhase);
|
||||
const cmsPreistraeger = useCmsCollection('preistraeger');
|
||||
const selectedWinners = fallbackArray(winnersSection.featured, []);
|
||||
const heroSecondaryCta = {
|
||||
label: fallbackText(hero.secondaryCta?.label, homeContent.hero.secondaryCta.label),
|
||||
url: fallbackText(hero.secondaryCta?.url, homeContent.hero.secondaryCta.url),
|
||||
};
|
||||
const showHeroSecondaryCta = !HIDE_MEMBERSHIP_HOME_HERO_CTA || !isMembershipCta(heroSecondaryCta);
|
||||
const selectedWinnerDocs = selectedWinners
|
||||
.map((selected) => resolveCmsRelationship(selected, cmsPreistraeger))
|
||||
.filter(Boolean)
|
||||
const eligibleWinners = (cmsPreistraeger.length ? cmsPreistraeger : WINNERS)
|
||||
.filter((winner) => Number((winner as { year?: string | number }).year) === 2025)
|
||||
const selectedWinnerIDs = new Set(
|
||||
selectedWinnerDocs.map((winner) => String((winner as WinnerCardData).id || (winner as WinnerCardData).slug)),
|
||||
)
|
||||
const remainingWinners = selectedWinnerDocs.length >= 8
|
||||
? eligibleWinners.filter((winner) => !selectedWinnerIDs.has(String((winner as WinnerCardData).id || (winner as WinnerCardData).slug)))
|
||||
: []
|
||||
const homeWinners = selectedWinnerDocs.length
|
||||
? [...selectedWinnerDocs, ...remainingWinners]
|
||||
: eligibleWinners;
|
||||
const homeWinners = resolveHomeWinners(winnersSection.featured, cmsPreistraeger, WINNERS);
|
||||
const scrollDesktopWinners = !isMobile && homeWinners.length > 8;
|
||||
const scrollWinnerGrid = isMobile || scrollDesktopWinners;
|
||||
const quickCriteria = fallbackArray(quickCheck.criteria, homeContent.quickCheck.criteria);
|
||||
|
||||
Reference in New Issue
Block a user