Event templates
This commit is contained in:
+75
-2
@@ -52,6 +52,22 @@ type DirectusFile = {
|
||||
type?: string;
|
||||
};
|
||||
|
||||
type EventTemplateRecord = {
|
||||
id: number;
|
||||
title?: string;
|
||||
slug?: string;
|
||||
description?: string;
|
||||
image?: string;
|
||||
logo?: string;
|
||||
booking_url?: string;
|
||||
};
|
||||
|
||||
type EventDateRecord = {
|
||||
id: number;
|
||||
date?: string;
|
||||
template?: EventTemplateRecord | number | null;
|
||||
};
|
||||
|
||||
function directusHeaders(): Record<string, string> | undefined {
|
||||
if (!directusToken) return undefined;
|
||||
return { Authorization: `Bearer ${directusToken}` };
|
||||
@@ -97,7 +113,7 @@ async function readDirectusEndpoint<T>(endpoint: URL): Promise<T[]> {
|
||||
return payload.data ?? [];
|
||||
}
|
||||
|
||||
function resolveDirectusAssetUrl(fileId: string): string {
|
||||
export function resolveDirectusAssetUrl(fileId: string): string {
|
||||
return new URL(`/assets/${fileId}`, directusPublicUrl).toString();
|
||||
}
|
||||
|
||||
@@ -138,6 +154,56 @@ async function getImagesFromFolder(folderName: string, fallbackImages: HomepageB
|
||||
export const getHomepageBannerImages = () => getImagesFromFolder(homepageBannerFolder, fallbackHomepageBannerImages);
|
||||
export const getCafePageImages = () => getImagesFromFolder(cafePageFolder, fallbackCafePageImages);
|
||||
|
||||
function stripHtml(value = ''): string {
|
||||
return value
|
||||
.replace(/<[^>]*>/g, ' ')
|
||||
.replace(/ /g, ' ')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/’/g, "'")
|
||||
.replace(/‘/g, "'")
|
||||
.replace(/“/g, '"')
|
||||
.replace(/”/g, '"')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
function mapEventDateToEventItem(eventDate: EventDateRecord): EventItem | null {
|
||||
if (!eventDate.date || !eventDate.template || typeof eventDate.template === 'number') return null;
|
||||
|
||||
const template = eventDate.template;
|
||||
if (!template.title || !template.slug) return null;
|
||||
|
||||
const description = template.description ?? '';
|
||||
const summary = stripHtml(description).slice(0, 180);
|
||||
|
||||
return {
|
||||
id: `${template.id}-${eventDate.id}`,
|
||||
date_id: eventDate.id,
|
||||
template_id: template.id,
|
||||
title: template.title,
|
||||
slug: template.slug,
|
||||
summary: summary ? `${summary}${summary.length === 180 ? '...' : ''}` : undefined,
|
||||
description,
|
||||
start_datetime: eventDate.date,
|
||||
realimage: template.image,
|
||||
logo: template.logo ? resolveDirectusAssetUrl(template.logo) : undefined,
|
||||
registration_link: template.booking_url,
|
||||
};
|
||||
}
|
||||
|
||||
async function getRecurringEvents(): Promise<EventItem[]> {
|
||||
const endpoint = new URL('/items/event_dates', directusUrl);
|
||||
endpoint.searchParams.set('limit', '100');
|
||||
endpoint.searchParams.set('sort', 'date');
|
||||
endpoint.searchParams.set(
|
||||
'fields',
|
||||
'id,date,template.id,template.title,template.slug,template.description,template.image,template.logo,template.booking_url',
|
||||
);
|
||||
|
||||
const eventDates = await readDirectusEndpoint<EventDateRecord>(endpoint);
|
||||
return eventDates.map(mapEventDateToEventItem).filter((event): event is EventItem => event !== null);
|
||||
}
|
||||
|
||||
function fallbackFor(collection: CollectionName) {
|
||||
switch (collection) {
|
||||
case 'news':
|
||||
@@ -156,7 +222,14 @@ function fallbackFor(collection: CollectionName) {
|
||||
}
|
||||
|
||||
export const getNews = () => readCollection<NewsItem>('news');
|
||||
export const getEvents = () => readCollection<EventItem>('events');
|
||||
export async function getEvents(): Promise<EventItem[]> {
|
||||
try {
|
||||
const recurringEvents = await getRecurringEvents();
|
||||
return recurringEvents.length > 0 ? recurringEvents : readCollection<EventItem>('events');
|
||||
} catch {
|
||||
return readCollection<EventItem>('events');
|
||||
}
|
||||
}
|
||||
export const getNotices = () => readCollection<Notice>('notices');
|
||||
export const getFuelPrices = () => readCollection<FuelPrice>('fuel_prices');
|
||||
export const getDocuments = () => readCollection<DocumentItem>('documents');
|
||||
|
||||
Reference in New Issue
Block a user