And now with files
This commit is contained in:
+86
-7
@@ -1,14 +1,17 @@
|
||||
import {
|
||||
fallbackCafePageImages,
|
||||
fallbackContacts,
|
||||
fallbackDocuments,
|
||||
fallbackEvents,
|
||||
fallbackFuelPrices,
|
||||
fallbackHomepageBannerImages,
|
||||
fallbackNews,
|
||||
fallbackNotices,
|
||||
type ContactItem,
|
||||
type DocumentItem,
|
||||
type EventItem,
|
||||
type FuelPrice,
|
||||
type HomepageBannerImage,
|
||||
type NewsItem,
|
||||
type Notice,
|
||||
} from './fallback-data';
|
||||
@@ -19,7 +22,7 @@ const defaultSortByCollection: Partial<Record<CollectionName, string>> = {
|
||||
news: '-publish_date',
|
||||
events: '-start_datetime',
|
||||
notices: '-priority',
|
||||
fuel_prices: '-last_updated',
|
||||
fuel_prices: 'fuel_type',
|
||||
documents: '-uploaded_at',
|
||||
contacts: 'order',
|
||||
};
|
||||
@@ -29,7 +32,30 @@ declare const process: {
|
||||
};
|
||||
|
||||
const directusUrl = process.env.DIRECTUS_URL ?? 'http://directus:8055';
|
||||
const directusPublicUrl = process.env.DIRECTUS_PUBLIC_URL && !process.env.DIRECTUS_PUBLIC_URL.includes('example.com')
|
||||
? process.env.DIRECTUS_PUBLIC_URL
|
||||
: directusUrl;
|
||||
const directusToken = process.env.DIRECTUS_ADMIN_TOKEN;
|
||||
const homepageBannerFolder = process.env.DIRECTUS_HOMEPAGE_BANNER_FOLDER ?? 'homepage-banners';
|
||||
const cafePageFolder = process.env.DIRECTUS_CAFE_PAGE_FOLDER ?? 'cafe-page';
|
||||
|
||||
type DirectusFolder = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type DirectusFile = {
|
||||
id: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
filename_download?: string;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
function directusHeaders(): Record<string, string> | undefined {
|
||||
if (!directusToken) return undefined;
|
||||
return { Authorization: `Bearer ${directusToken}` };
|
||||
}
|
||||
|
||||
async function readCollection<T>(collection: CollectionName): Promise<T[]> {
|
||||
const endpoint = new URL(`/items/${collection}`, directusUrl);
|
||||
@@ -40,13 +66,8 @@ async function readCollection<T>(collection: CollectionName): Promise<T[]> {
|
||||
}
|
||||
|
||||
try {
|
||||
const headers: Record<string, string> = {};
|
||||
if (directusToken) {
|
||||
headers['Authorization'] = `Bearer ${directusToken}`;
|
||||
}
|
||||
|
||||
const response = await fetch(endpoint, {
|
||||
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
||||
headers: directusHeaders(),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Directus responded with ${response.status}`);
|
||||
@@ -59,6 +80,64 @@ async function readCollection<T>(collection: CollectionName): Promise<T[]> {
|
||||
}
|
||||
}
|
||||
|
||||
async function readDirectusEndpoint<T>(endpoint: URL): Promise<T[]> {
|
||||
let response = await fetch(endpoint, {
|
||||
headers: directusHeaders(),
|
||||
});
|
||||
|
||||
if (response.status === 403 && directusToken) {
|
||||
response = await fetch(endpoint);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Directus responded with ${response.status}`);
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as { data?: T[] };
|
||||
return payload.data ?? [];
|
||||
}
|
||||
|
||||
function resolveDirectusAssetUrl(fileId: string): string {
|
||||
return new URL(`/assets/${fileId}`, directusPublicUrl).toString();
|
||||
}
|
||||
|
||||
async function findFolderByName(name: string): Promise<DirectusFolder | null> {
|
||||
const endpoint = new URL('/folders', directusUrl);
|
||||
endpoint.searchParams.set('limit', '1');
|
||||
endpoint.searchParams.set('filter[name][_eq]', name);
|
||||
endpoint.searchParams.set('fields', 'id,name');
|
||||
|
||||
const folders = await readDirectusEndpoint<DirectusFolder>(endpoint);
|
||||
return folders[0] ?? null;
|
||||
}
|
||||
|
||||
async function getImagesFromFolder(folderName: string, fallbackImages: HomepageBannerImage[]): Promise<HomepageBannerImage[]> {
|
||||
try {
|
||||
const folder = await findFolderByName(folderName);
|
||||
if (!folder) return fallbackImages;
|
||||
|
||||
const endpoint = new URL('/files', directusUrl);
|
||||
endpoint.searchParams.set('limit', '20');
|
||||
endpoint.searchParams.set('sort', '-uploaded_on');
|
||||
endpoint.searchParams.set('filter[folder][_eq]', folder.id);
|
||||
endpoint.searchParams.set('filter[type][_starts_with]', 'image/');
|
||||
endpoint.searchParams.set('fields', 'id,title,description,filename_download,type');
|
||||
|
||||
const files = await readDirectusEndpoint<DirectusFile>(endpoint);
|
||||
const images = files.map((file) => ({
|
||||
src: resolveDirectusAssetUrl(file.id),
|
||||
alt: file.description || file.title || file.filename_download || 'Swansea Airport',
|
||||
}));
|
||||
|
||||
return images.length > 0 ? images : fallbackImages;
|
||||
} catch {
|
||||
return fallbackImages;
|
||||
}
|
||||
}
|
||||
|
||||
export const getHomepageBannerImages = () => getImagesFromFolder(homepageBannerFolder, fallbackHomepageBannerImages);
|
||||
export const getCafePageImages = () => getImagesFromFolder(cafePageFolder, fallbackCafePageImages);
|
||||
|
||||
function fallbackFor(collection: CollectionName) {
|
||||
switch (collection) {
|
||||
case 'news':
|
||||
|
||||
Reference in New Issue
Block a user