feat: manage press fallback card media
This commit is contained in:
@@ -35,6 +35,7 @@ const eventFields: Field[] = [
|
|||||||
text('location', 'Location'),
|
text('location', 'Location'),
|
||||||
text('cat', 'Category'),
|
text('cat', 'Category'),
|
||||||
text('status', 'Status'),
|
text('status', 'Status'),
|
||||||
|
uploadField('image', 'Image'),
|
||||||
text('img', 'Image URL or path'),
|
text('img', 'Image URL or path'),
|
||||||
textarea('desc', 'Description'),
|
textarea('desc', 'Description'),
|
||||||
text('slug', 'Route'),
|
text('slug', 'Route'),
|
||||||
@@ -49,6 +50,7 @@ const newsFields: Field[] = [
|
|||||||
text('title', 'Title'),
|
text('title', 'Title'),
|
||||||
textarea('excerpt', 'Excerpt'),
|
textarea('excerpt', 'Excerpt'),
|
||||||
text('cat', 'Category'),
|
text('cat', 'Category'),
|
||||||
|
uploadField('image', 'Image'),
|
||||||
text('img', 'Image URL or path'),
|
text('img', 'Image URL or path'),
|
||||||
text('slug', 'Route'),
|
text('slug', 'Route'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1543,6 +1543,7 @@ export interface Page {
|
|||||||
location?: string | null;
|
location?: string | null;
|
||||||
cat?: string | null;
|
cat?: string | null;
|
||||||
status?: string | null;
|
status?: string | null;
|
||||||
|
image?: (number | null) | Media;
|
||||||
img?: string | null;
|
img?: string | null;
|
||||||
desc?: string | null;
|
desc?: string | null;
|
||||||
slug?: string | null;
|
slug?: string | null;
|
||||||
@@ -1569,6 +1570,7 @@ export interface Page {
|
|||||||
title?: string | null;
|
title?: string | null;
|
||||||
excerpt?: string | null;
|
excerpt?: string | null;
|
||||||
cat?: string | null;
|
cat?: string | null;
|
||||||
|
image?: (number | null) | Media;
|
||||||
img?: string | null;
|
img?: string | null;
|
||||||
slug?: string | null;
|
slug?: string | null;
|
||||||
id?: string | null;
|
id?: string | null;
|
||||||
@@ -4443,6 +4445,7 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
location?: T;
|
location?: T;
|
||||||
cat?: T;
|
cat?: T;
|
||||||
status?: T;
|
status?: T;
|
||||||
|
image?: T;
|
||||||
img?: T;
|
img?: T;
|
||||||
desc?: T;
|
desc?: T;
|
||||||
slug?: T;
|
slug?: T;
|
||||||
@@ -4465,6 +4468,7 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
title?: T;
|
title?: T;
|
||||||
excerpt?: T;
|
excerpt?: T;
|
||||||
cat?: T;
|
cat?: T;
|
||||||
|
image?: T;
|
||||||
img?: T;
|
img?: T;
|
||||||
slug?: T;
|
slug?: T;
|
||||||
id?: T;
|
id?: T;
|
||||||
|
|||||||
@@ -15,6 +15,22 @@ const mediaByFilename = async (payload: Payload, filename: string) => {
|
|||||||
return result.docs[0]?.id
|
return result.docs[0]?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filenameFromPath = (source: string) => source.split('?')[0]?.split('/').filter(Boolean).pop()
|
||||||
|
|
||||||
|
const fallbackItemsWithImages = async <T extends { img?: string }>(
|
||||||
|
payload: Payload,
|
||||||
|
items: T[],
|
||||||
|
) =>
|
||||||
|
Promise.all(
|
||||||
|
items.map(async (item) => {
|
||||||
|
const filename = item.img ? filenameFromPath(item.img) : undefined
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
image: filename ? await mediaByFilename(payload, filename) : undefined,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const payload = await getPayload({ config })
|
const payload = await getPayload({ config })
|
||||||
|
|
||||||
@@ -41,6 +57,10 @@ async function main() {
|
|||||||
const { imageFilename: _heroFilename, ...heroContent } = pressIndexContent.hero
|
const { imageFilename: _heroFilename, ...heroContent } = pressIndexContent.hero
|
||||||
const { collectionFallbackImageFilename: _eventFallbackFilename, ...eventsContent } = pressIndexContent.events
|
const { collectionFallbackImageFilename: _eventFallbackFilename, ...eventsContent } = pressIndexContent.events
|
||||||
const { collectionFallbackImageFilename: _newsFallbackFilename, ...newsContent } = pressIndexContent.news
|
const { collectionFallbackImageFilename: _newsFallbackFilename, ...newsContent } = pressIndexContent.news
|
||||||
|
const [eventFallbackItems, newsFallbackItems] = await Promise.all([
|
||||||
|
fallbackItemsWithImages(payload, pressIndexContent.events.fallbackItems),
|
||||||
|
fallbackItemsWithImages(payload, pressIndexContent.news.fallbackItems),
|
||||||
|
])
|
||||||
|
|
||||||
await payload.update({
|
await payload.update({
|
||||||
collection: 'pages',
|
collection: 'pages',
|
||||||
@@ -57,10 +77,12 @@ async function main() {
|
|||||||
events: {
|
events: {
|
||||||
...eventsContent,
|
...eventsContent,
|
||||||
collectionFallbackImage: eventFallbackImage,
|
collectionFallbackImage: eventFallbackImage,
|
||||||
|
fallbackItems: eventFallbackItems,
|
||||||
},
|
},
|
||||||
news: {
|
news: {
|
||||||
...newsContent,
|
...newsContent,
|
||||||
collectionFallbackImage: newsFallbackImage,
|
collectionFallbackImage: newsFallbackImage,
|
||||||
|
fallbackItems: newsFallbackItems,
|
||||||
},
|
},
|
||||||
downloads: {
|
downloads: {
|
||||||
...pressIndexContent.downloads,
|
...pressIndexContent.downloads,
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ const FB = '"Inter", sans-serif';
|
|||||||
|
|
||||||
type PressIndexCms = Partial<typeof pressIndexContent> & {
|
type PressIndexCms = Partial<typeof pressIndexContent> & {
|
||||||
hero?: Partial<typeof pressIndexContent.hero> & { image?: unknown }
|
hero?: Partial<typeof pressIndexContent.hero> & { image?: unknown }
|
||||||
events?: Partial<typeof pressIndexContent.events> & { collectionFallbackImage?: unknown }
|
events?: Partial<typeof pressIndexContent.events> & { collectionFallbackImage?: unknown; fallbackItems?: PressEventItem[] }
|
||||||
news?: Partial<typeof pressIndexContent.news> & { collectionFallbackImage?: unknown }
|
news?: Partial<typeof pressIndexContent.news> & { collectionFallbackImage?: unknown; fallbackItems?: PressNewsItem[] }
|
||||||
downloads?: Partial<typeof pressIndexContent.downloads> & { kitFile?: unknown }
|
downloads?: Partial<typeof pressIndexContent.downloads> & { kitFile?: unknown }
|
||||||
}
|
}
|
||||||
|
|
||||||
type PressEventItem = (typeof pressIndexContent.events.fallbackItems)[number]
|
type PressEventItem = (typeof pressIndexContent.events.fallbackItems)[number] & { image?: unknown }
|
||||||
type PressNewsItem = (typeof pressIndexContent.news.fallbackItems)[number]
|
type PressNewsItem = (typeof pressIndexContent.news.fallbackItems)[number] & { image?: unknown }
|
||||||
|
|
||||||
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 fallbackArray = <T,>(value: unknown, fallback: T[]) => Array.isArray(value) && value.length ? value as T[] : fallback;
|
const fallbackArray = <T,>(value: unknown, fallback: T[]) => Array.isArray(value) && value.length ? value as T[] : fallback;
|
||||||
@@ -73,6 +73,8 @@ function Lines({ text }: { text: string }) {
|
|||||||
return <>{text.split('\n').map((line, i) => <React.Fragment key={`${line}-${i}`}>{i > 0 && <br />}{line}</React.Fragment>)}</>
|
return <>{text.split('\n').map((line, i) => <React.Fragment key={`${line}-${i}`}>{i > 0 && <br />}{line}</React.Fragment>)}</>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fallbackCardImage = (item: PressEventItem | PressNewsItem) => mediaUrl(item.image, fallbackText(item.img, ''))
|
||||||
|
|
||||||
function NewsCard({ item, idx, isMobile, readMoreLabel, total }: { item: PressNewsItem; idx: number; isMobile: boolean; readMoreLabel: string; total: number }) {
|
function NewsCard({ item, idx, isMobile, readMoreLabel, total }: { item: PressNewsItem; idx: number; isMobile: boolean; readMoreLabel: string; total: number }) {
|
||||||
const [hovered, setHovered] = React.useState(false);
|
const [hovered, setHovered] = React.useState(false);
|
||||||
return (
|
return (
|
||||||
@@ -92,7 +94,7 @@ function NewsCard({ item, idx, isMobile, readMoreLabel, total }: { item: PressNe
|
|||||||
{/* image */}
|
{/* image */}
|
||||||
<div style={{ position: 'relative', overflow: 'hidden', height: 220 }}>
|
<div style={{ position: 'relative', overflow: 'hidden', height: 220 }}>
|
||||||
<Image unoptimized
|
<Image unoptimized
|
||||||
src={item.img}
|
src={fallbackCardImage(item)}
|
||||||
alt={item.title}
|
alt={item.title}
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -422,7 +424,7 @@ const Press: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{/* Left – image cell */}
|
{/* Left – image cell */}
|
||||||
<div style={{ position: 'relative', overflow: 'hidden', height: isMobile ? 200 : 240 }}>
|
<div style={{ position: 'relative', overflow: 'hidden', height: isMobile ? 200 : 240 }}>
|
||||||
<Image unoptimized src={event.img} alt={event.title} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
|
<Image unoptimized src={fallbackCardImage(event)} alt={event.title} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
|
||||||
<div style={{ position: 'absolute', top: 20, left: 20, padding: '5px 12px', fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase' as const, letterSpacing: '0.18em', background: event.status === fallbackText(eventsSection.openStatusLabel, pressIndexContent.events.openStatusLabel) ? GOLD : 'rgba(3,9,58,0.85)', color: event.status === fallbackText(eventsSection.openStatusLabel, pressIndexContent.events.openStatusLabel) ? NAVY : 'rgba(255,255,255,0.6)' }}>
|
<div style={{ position: 'absolute', top: 20, left: 20, padding: '5px 12px', fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase' as const, letterSpacing: '0.18em', background: event.status === fallbackText(eventsSection.openStatusLabel, pressIndexContent.events.openStatusLabel) ? GOLD : 'rgba(3,9,58,0.85)', color: event.status === fallbackText(eventsSection.openStatusLabel, pressIndexContent.events.openStatusLabel) ? NAVY : 'rgba(255,255,255,0.6)' }}>
|
||||||
{event.status}
|
{event.status}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user