|
|
|
|
@@ -2,9 +2,15 @@ import React from 'react';
|
|
|
|
|
import { Calendar, MapPin } from 'lucide-react';
|
|
|
|
|
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
|
|
|
|
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
|
|
|
|
import { useCmsCollection, useCmsRoute, type CmsRouteDoc } from '@/spa/cmsRoute';
|
|
|
|
|
import { docImageUrl, mediaAlt, mediaUrl } from '@/spa/cmsMediaField';
|
|
|
|
|
import { useCmsCollection, useCmsRoute } from '@/spa/cmsRoute';
|
|
|
|
|
import { mediaAlt, mediaUrl } from '@/spa/cmsMediaField';
|
|
|
|
|
import Image from '@/spa/components/ui/UnoptimizedImage'
|
|
|
|
|
import {
|
|
|
|
|
pressEventsFromCms,
|
|
|
|
|
pressNewsFromCms,
|
|
|
|
|
type PressEventItem,
|
|
|
|
|
type PressNewsItem,
|
|
|
|
|
} from '@/spa/pressCollectionItems';
|
|
|
|
|
import { pressIndexContent } from '@/spa/pressIndexContent';
|
|
|
|
|
import { Link } from '@/spa/router';
|
|
|
|
|
|
|
|
|
|
@@ -15,14 +21,11 @@ const FB = '"Inter", sans-serif';
|
|
|
|
|
|
|
|
|
|
type PressIndexCms = Partial<typeof pressIndexContent> & {
|
|
|
|
|
hero?: Partial<typeof pressIndexContent.hero> & { image?: unknown }
|
|
|
|
|
events?: Partial<typeof pressIndexContent.events> & { collectionFallbackImage?: unknown; fallbackItems?: PressEventItem[] }
|
|
|
|
|
news?: Partial<typeof pressIndexContent.news> & { collectionFallbackImage?: unknown; fallbackItems?: PressNewsItem[] }
|
|
|
|
|
events?: Partial<typeof pressIndexContent.events> & { collectionFallbackImage?: unknown }
|
|
|
|
|
news?: Partial<typeof pressIndexContent.news> & { collectionFallbackImage?: unknown }
|
|
|
|
|
downloads?: Partial<typeof pressIndexContent.downloads> & { kitFile?: unknown }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PressEventItem = (typeof pressIndexContent.events.fallbackItems)[number] & { image?: unknown }
|
|
|
|
|
type PressNewsItem = (typeof pressIndexContent.news.fallbackItems)[number] & { image?: unknown }
|
|
|
|
|
|
|
|
|
|
const fallbackText = (value: unknown, fallback: string) => typeof value === 'string' && value.length > 0 ? value : fallback;
|
|
|
|
|
const fallbackArray = <T,>(value: unknown, fallback: T[]) => Array.isArray(value) && value.length ? value as T[] : fallback;
|
|
|
|
|
|
|
|
|
|
@@ -39,43 +42,6 @@ const statusLabelMap = (items: unknown) =>
|
|
|
|
|
return labels
|
|
|
|
|
}, {})
|
|
|
|
|
|
|
|
|
|
const normalizeStatus = (status: unknown, labels: Record<string, string>, defaultStatusLabel: string) => {
|
|
|
|
|
const value = fallbackText(status, defaultStatusLabel)
|
|
|
|
|
return labels[value] || value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const detailPath = (spaPath: unknown, slug: unknown, prefix: '/presse/events' | '/presse/blog') => {
|
|
|
|
|
const path = fallbackText(spaPath, '')
|
|
|
|
|
if (path.startsWith(`${prefix}/`)) return path
|
|
|
|
|
|
|
|
|
|
const pathSlug = fallbackText(slug, '').replace(/^\/+/, '')
|
|
|
|
|
return pathSlug ? `${prefix}/${pathSlug}` : prefix
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const eventFromCms = (
|
|
|
|
|
event: CmsRouteDoc,
|
|
|
|
|
fallbackImage: string,
|
|
|
|
|
labels: Record<string, string>,
|
|
|
|
|
eventsSection: NonNullable<PressIndexCms['events']>,
|
|
|
|
|
): PressEventItem => ({
|
|
|
|
|
title: String(event.title || fallbackText(eventsSection.missingTitleLabel, pressIndexContent.events.missingTitleLabel)),
|
|
|
|
|
date: String(event.date || fallbackText(eventsSection.missingDateLabel, pressIndexContent.events.missingDateLabel)),
|
|
|
|
|
location: String(event.location || event.venue || fallbackText(eventsSection.missingLocationLabel, pressIndexContent.events.missingLocationLabel)),
|
|
|
|
|
cat: String(event.category || fallbackText(eventsSection.missingCategoryLabel, pressIndexContent.events.missingCategoryLabel)),
|
|
|
|
|
status: normalizeStatus(event.status, labels, fallbackText(eventsSection.defaultStatusLabel, pressIndexContent.events.defaultStatusLabel)),
|
|
|
|
|
img: docImageUrl(event, fallbackImage),
|
|
|
|
|
desc: String(event.description || event.meta?.description || ''),
|
|
|
|
|
slug: detailPath(event.spaPath, event.slug, '/presse/events'),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const postFromCms = (post: CmsRouteDoc, fallbackImage: string, newsSection: NonNullable<PressIndexCms['news']>): PressNewsItem => ({
|
|
|
|
|
title: String(post.title || fallbackText(newsSection.missingTitleLabel, pressIndexContent.news.missingTitleLabel)),
|
|
|
|
|
excerpt: String(post.excerpt || post.meta?.description || ''),
|
|
|
|
|
cat: String(post.cat || fallbackText(newsSection.missingCategoryLabel, pressIndexContent.news.missingCategoryLabel)),
|
|
|
|
|
img: docImageUrl(post, fallbackImage, 'heroImage'),
|
|
|
|
|
slug: detailPath(post.spaPath, post.slug, '/presse/blog'),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function Lines({ text }: { text: string }) {
|
|
|
|
|
return <>{text.split('\n').map((line, i) => <React.Fragment key={`${line}-${i}`}>{i > 0 && <br />}{line}</React.Fragment>)}</>
|
|
|
|
|
}
|
|
|
|
|
@@ -185,23 +151,14 @@ const Press: React.FC = () => {
|
|
|
|
|
const eventStatusLabels = React.useMemo(() => statusLabelMap(eventsSection.statusLabels), [eventsSection.statusLabels]);
|
|
|
|
|
const eventCollectionFallbackImage = mediaUrl(eventsSection.collectionFallbackImage, `/images/${pressIndexContent.events.collectionFallbackImageFilename}`);
|
|
|
|
|
const newsCollectionFallbackImage = mediaUrl(newsSection.collectionFallbackImage, `/images/${pressIndexContent.news.collectionFallbackImageFilename}`);
|
|
|
|
|
const combinedEvents = React.useMemo(() => {
|
|
|
|
|
if (cmsEvents.length) {
|
|
|
|
|
return cmsEvents.map((event) =>
|
|
|
|
|
eventFromCms(
|
|
|
|
|
event,
|
|
|
|
|
eventCollectionFallbackImage,
|
|
|
|
|
eventStatusLabels,
|
|
|
|
|
eventsSection,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return fallbackArray<PressEventItem>(eventsSection.fallbackItems, pressIndexContent.events.fallbackItems);
|
|
|
|
|
}, [cmsEvents, eventCollectionFallbackImage, eventStatusLabels, eventsSection]);
|
|
|
|
|
const combinedNews = React.useMemo(() => {
|
|
|
|
|
if (cmsPosts.length) return cmsPosts.map((post) => postFromCms(post, newsCollectionFallbackImage, newsSection));
|
|
|
|
|
return fallbackArray<PressNewsItem>(newsSection.fallbackItems, pressIndexContent.news.fallbackItems);
|
|
|
|
|
}, [cmsPosts, newsCollectionFallbackImage, newsSection]);
|
|
|
|
|
const combinedEvents = React.useMemo(
|
|
|
|
|
() => pressEventsFromCms(cmsEvents, eventCollectionFallbackImage, eventStatusLabels, eventsSection),
|
|
|
|
|
[cmsEvents, eventCollectionFallbackImage, eventStatusLabels, eventsSection],
|
|
|
|
|
);
|
|
|
|
|
const combinedNews = React.useMemo(
|
|
|
|
|
() => pressNewsFromCms(cmsPosts, newsCollectionFallbackImage, newsSection),
|
|
|
|
|
[cmsPosts, newsCollectionFallbackImage, newsSection],
|
|
|
|
|
);
|
|
|
|
|
return (
|
|
|
|
|
<div className="animate-fade-in">
|
|
|
|
|
|
|
|
|
|
|