feat: manage event detail fallback media via payload
This commit is contained in:
@@ -130,6 +130,15 @@ export const Events: CollectionConfig = {
|
|||||||
'Shared labels, status/update labels, subscription copy, CTAs, and formatting copy for the Event detail route.',
|
'Shared labels, status/update labels, subscription copy, CTAs, and formatting copy for the Event detail route.',
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'fallbackImage',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
label: 'Fallback hero image',
|
||||||
|
admin: {
|
||||||
|
description: `Current frontend fallback image: /images/${eventDetailContent.fallbackImageFilename}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'notFound',
|
name: 'notFound',
|
||||||
label: 'Not found state',
|
label: 'Not found state',
|
||||||
|
|||||||
@@ -2845,6 +2845,10 @@ export interface Event {
|
|||||||
* Shared labels, status/update labels, subscription copy, CTAs, and formatting copy for the Event detail route.
|
* Shared labels, status/update labels, subscription copy, CTAs, and formatting copy for the Event detail route.
|
||||||
*/
|
*/
|
||||||
detailPage?: {
|
detailPage?: {
|
||||||
|
/**
|
||||||
|
* Current frontend fallback image: /images/buehne-moderatoren.jpg
|
||||||
|
*/
|
||||||
|
fallbackImage?: (number | null) | Media;
|
||||||
notFound?: {
|
notFound?: {
|
||||||
title?: string | null;
|
title?: string | null;
|
||||||
backLabel?: string | null;
|
backLabel?: string | null;
|
||||||
@@ -5088,6 +5092,7 @@ export interface EventsSelect<T extends boolean = true> {
|
|||||||
detailPage?:
|
detailPage?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
|
fallbackImage?: T;
|
||||||
notFound?:
|
notFound?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
import 'dotenv/config'
|
import 'dotenv/config'
|
||||||
|
|
||||||
import config from '@payload-config'
|
import config from '@payload-config'
|
||||||
import { getPayload } from 'payload'
|
import { getPayload, type Payload } from 'payload'
|
||||||
|
|
||||||
import { eventDetailContent } from '@/spa/eventDetailContent'
|
import { eventDetailContent } from '@/spa/eventDetailContent'
|
||||||
|
|
||||||
|
const mediaByFilename = async (payload: Payload, filename: string) => {
|
||||||
|
const result = await payload.find({
|
||||||
|
collection: 'media',
|
||||||
|
limit: 1,
|
||||||
|
pagination: false,
|
||||||
|
where: { filename: { equals: filename } },
|
||||||
|
})
|
||||||
|
return result.docs[0]?.id
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const payload = await getPayload({ config })
|
const payload = await getPayload({ config })
|
||||||
|
const fallbackImage = await mediaByFilename(payload, eventDetailContent.fallbackImageFilename)
|
||||||
|
const { fallbackImageFilename: _fallbackImageFilename, ...detailContent } = eventDetailContent
|
||||||
|
|
||||||
const events = await payload.find({
|
const events = await payload.find({
|
||||||
collection: 'events',
|
collection: 'events',
|
||||||
@@ -25,7 +37,8 @@ async function main() {
|
|||||||
context: { disableRevalidate: true },
|
context: { disableRevalidate: true },
|
||||||
data: {
|
data: {
|
||||||
detailPage: {
|
detailPage: {
|
||||||
...eventDetailContent,
|
...detailContent,
|
||||||
|
fallbackImage,
|
||||||
updatesCopy: eventDetailContent.updates,
|
updatesCopy: eventDetailContent.updates,
|
||||||
},
|
},
|
||||||
} as never,
|
} as never,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export const eventDetailContent = {
|
export const eventDetailContent = {
|
||||||
|
fallbackImageFilename: 'buehne-moderatoren.jpg',
|
||||||
notFound: {
|
notFound: {
|
||||||
title: 'Event nicht gefunden',
|
title: 'Event nicht gefunden',
|
||||||
backLabel: 'Zurück zur Presse-Seite',
|
backLabel: 'Zurück zur Presse-Seite',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { motion } from 'framer-motion'
|
|||||||
import { Calendar, MapPin, Clock, Bell, BellOff, ArrowLeft, ChevronRight } from 'lucide-react'
|
import { Calendar, MapPin, Clock, Bell, BellOff, ArrowLeft, ChevronRight } from 'lucide-react'
|
||||||
import { getEventBySlug, EventUpdate, type BmpEvent, type EventEckdaten } from '@/spa/data/events'
|
import { getEventBySlug, EventUpdate, type BmpEvent, type EventEckdaten } from '@/spa/data/events'
|
||||||
import { useCmsRoute } from '@/spa/cmsRoute'
|
import { useCmsRoute } from '@/spa/cmsRoute'
|
||||||
import { docImageUrl } from '@/spa/cmsMediaField'
|
import { docImageUrl, mediaUrl } from '@/spa/cmsMediaField'
|
||||||
import { useIsMobile } from '@/spa/hooks/useIsMobile'
|
import { useIsMobile } from '@/spa/hooks/useIsMobile'
|
||||||
import { eventDetailContent } from '@/spa/eventDetailContent'
|
import { eventDetailContent } from '@/spa/eventDetailContent'
|
||||||
import Image from '@/spa/components/ui/UnoptimizedImage'
|
import Image from '@/spa/components/ui/UnoptimizedImage'
|
||||||
@@ -14,6 +14,7 @@ const GOLD = '#EFBF04'
|
|||||||
const CREAM = '#EFE5E3'
|
const CREAM = '#EFE5E3'
|
||||||
|
|
||||||
type EventDetailCms = Omit<Partial<typeof eventDetailContent>, 'updateStyles' | 'statusStyles'> & {
|
type EventDetailCms = Omit<Partial<typeof eventDetailContent>, 'updateStyles' | 'statusStyles'> & {
|
||||||
|
fallbackImage?: unknown
|
||||||
updateStyles?: unknown
|
updateStyles?: unknown
|
||||||
statusStyles?: unknown
|
statusStyles?: unknown
|
||||||
updatesCopy?: Partial<typeof eventDetailContent.updates>
|
updatesCopy?: Partial<typeof eventDetailContent.updates>
|
||||||
@@ -96,6 +97,8 @@ export default function EventDetail() {
|
|||||||
const { slug } = useParams<{ slug: string }>()
|
const { slug } = useParams<{ slug: string }>()
|
||||||
const route = useCmsRoute()
|
const route = useCmsRoute()
|
||||||
const cmsEvent = route?.collection === 'events' ? route.doc : undefined
|
const cmsEvent = route?.collection === 'events' ? route.doc : undefined
|
||||||
|
const cmsDetail = getDetailPage(cmsEvent?.detailPage)
|
||||||
|
const eventFallbackImage = mediaUrl(cmsDetail.fallbackImage, `/images/${eventDetailContent.fallbackImageFilename}`)
|
||||||
const event = getEventBySlug(slug ?? '') || (cmsEvent ? {
|
const event = getEventBySlug(slug ?? '') || (cmsEvent ? {
|
||||||
slug: String(cmsEvent.slug || slug),
|
slug: String(cmsEvent.slug || slug),
|
||||||
title: String(cmsEvent.title || 'Event'),
|
title: String(cmsEvent.title || 'Event'),
|
||||||
@@ -106,14 +109,14 @@ export default function EventDetail() {
|
|||||||
venue: String(cmsEvent.venue || 'Ort folgt'),
|
venue: String(cmsEvent.venue || 'Ort folgt'),
|
||||||
category: String(cmsEvent.category || 'Event'),
|
category: String(cmsEvent.category || 'Event'),
|
||||||
status: (cmsEvent.status as BmpEvent['status']) || 'geplant',
|
status: (cmsEvent.status as BmpEvent['status']) || 'geplant',
|
||||||
img: docImageUrl(cmsEvent, '/images/buehne-moderatoren.jpg'),
|
img: docImageUrl(cmsEvent, eventFallbackImage),
|
||||||
description: String(cmsEvent.description || cmsEvent.meta?.description || ''),
|
description: String(cmsEvent.description || cmsEvent.meta?.description || ''),
|
||||||
longDescription: String(cmsEvent.longDescription || cmsEvent.description || cmsEvent.meta?.description || 'Dieses Event wird aus Payload CMS geladen.'),
|
longDescription: String(cmsEvent.longDescription || cmsEvent.description || cmsEvent.meta?.description || 'Dieses Event wird aus Payload CMS geladen.'),
|
||||||
eckdaten: Array.isArray(cmsEvent.eckdaten) ? cmsEvent.eckdaten as EventEckdaten[] : [],
|
eckdaten: Array.isArray(cmsEvent.eckdaten) ? cmsEvent.eckdaten as EventEckdaten[] : [],
|
||||||
updates: Array.isArray(cmsEvent.updates) ? cmsEvent.updates as EventUpdate[] : [],
|
updates: Array.isArray(cmsEvent.updates) ? cmsEvent.updates as EventUpdate[] : [],
|
||||||
detailPage: cmsEvent.detailPage,
|
detailPage: cmsEvent.detailPage,
|
||||||
} as BmpEvent : undefined)
|
} as BmpEvent : undefined)
|
||||||
const detail = getDetailPage(event && 'detailPage' in event ? event.detailPage : undefined)
|
const detail = getDetailPage(event && 'detailPage' in event ? event.detailPage : cmsDetail)
|
||||||
const notFound = detail.notFound || eventDetailContent.notFound
|
const notFound = detail.notFound || eventDetailContent.notFound
|
||||||
const heroBackLink = detail.heroBackLink || eventDetailContent.heroBackLink
|
const heroBackLink = detail.heroBackLink || eventDetailContent.heroBackLink
|
||||||
const sections = detail.sections || eventDetailContent.sections
|
const sections = detail.sections || eventDetailContent.sections
|
||||||
|
|||||||
Reference in New Issue
Block a user