Updates
This commit is contained in:
@@ -70,6 +70,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
PUBLIC_SITE_URL: ${PUBLIC_SITE_URL}
|
PUBLIC_SITE_URL: ${PUBLIC_SITE_URL}
|
||||||
DIRECTUS_URL: ${DIRECTUS_URL}
|
DIRECTUS_URL: ${DIRECTUS_URL}
|
||||||
|
DIRECTUS_PUBLIC_URL: ${DIRECTUS_PUBLIC_URL}
|
||||||
|
DIRECTUS_PORT: ${DIRECTUS_PORT}
|
||||||
DIRECTUS_ADMIN_TOKEN: ${DIRECTUS_ADMIN_TOKEN}
|
DIRECTUS_ADMIN_TOKEN: ${DIRECTUS_ADMIN_TOKEN}
|
||||||
depends_on:
|
depends_on:
|
||||||
directus:
|
directus:
|
||||||
|
|||||||
@@ -16,24 +16,29 @@ const { events, title = 'Upcoming events', description = 'A quick scan list for
|
|||||||
<SectionHeading eyebrow="Events" title={title} description={description} />
|
<SectionHeading eyebrow="Events" title={title} description={description} />
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
{events.length > 0 ? (
|
{events.length > 0 ? (
|
||||||
events.map((event) => (
|
events.map((event) => {
|
||||||
<article class="card">
|
const detailHref = event.slug ? `/events/${event.slug}/` : undefined;
|
||||||
<div class="split-grid" style="align-items:start;">
|
|
||||||
<div>
|
return (
|
||||||
<p class="pill">{event.is_featured ? 'Featured' : 'Event'}</p>
|
<article class="card">
|
||||||
<h3>{event.title}</h3>
|
<div class="split-grid" style="align-items:start;">
|
||||||
<p>{event.description}</p>
|
<div>
|
||||||
|
<p class="pill">{event.is_featured ? 'Featured' : 'Event'}</p>
|
||||||
|
<h3>{detailHref ? <a href={detailHref}>{event.title}</a> : event.title}</h3>
|
||||||
|
<p>{event.description}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="meta">{formatDateTime(event.start_datetime)}</p>
|
||||||
|
{event.location_text && <p>{event.location_text}</p>}
|
||||||
|
{detailHref && <p><a class="button primary" href={detailHref}>View event</a></p>}
|
||||||
|
{event.registration_link && (
|
||||||
|
<p><a class="button secondary" href={event.registration_link}>Register</a></p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</article>
|
||||||
<p class="meta">{formatDateTime(event.start_datetime)}</p>
|
);
|
||||||
{event.location_text && <p>{event.location_text}</p>}
|
})
|
||||||
{event.registration_link && (
|
|
||||||
<p><a class="button secondary" href={event.registration_link}>Register</a></p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
))
|
|
||||||
) : (
|
) : (
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>No events published</h3>
|
<h3>No events published</h3>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export type EventItem = {
|
|||||||
end_datetime?: string;
|
end_datetime?: string;
|
||||||
location_text?: string;
|
location_text?: string;
|
||||||
registration_link?: string;
|
registration_link?: string;
|
||||||
|
realimage?: string | { id?: string; filename_download?: string; title?: string };
|
||||||
status?: string;
|
status?: string;
|
||||||
is_featured?: boolean;
|
is_featured?: boolean;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
|
|||||||
@@ -5,18 +5,46 @@ import { formatDateTime } from '../../lib/format';
|
|||||||
|
|
||||||
type EventItem = Awaited<ReturnType<typeof getEvents>>[number];
|
type EventItem = Awaited<ReturnType<typeof getEvents>>[number];
|
||||||
|
|
||||||
|
declare const process: {
|
||||||
|
env: Record<string, string | undefined>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function resolveEventImageSource(realimage: EventItem['realimage']): string | null {
|
||||||
|
if (!realimage) return null;
|
||||||
|
|
||||||
|
const candidate = typeof realimage === 'string' ? realimage : realimage.id;
|
||||||
|
if (!candidate) return null;
|
||||||
|
|
||||||
|
if (candidate.startsWith('http://') || candidate.startsWith('https://') || candidate.startsWith('/')) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
const configuredPublicUrl = process.env.DIRECTUS_PUBLIC_URL;
|
||||||
|
const directusPort = process.env.DIRECTUS_PORT ?? '8066';
|
||||||
|
const localFallbackUrl = `${Astro.url.protocol}//${Astro.url.hostname}:${directusPort}`;
|
||||||
|
const directusBaseUrl =
|
||||||
|
configuredPublicUrl && !configuredPublicUrl.includes('example.com')
|
||||||
|
? configuredPublicUrl
|
||||||
|
: localFallbackUrl;
|
||||||
|
|
||||||
|
return new URL(`/assets/${candidate}`, directusBaseUrl).toString();
|
||||||
|
}
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const events = await getEvents();
|
const events = await getEvents();
|
||||||
return events.map((item) => ({ params: { slug: item.slug }, props: { item } }));
|
return events.map((item) => ({ params: { slug: item.slug }, props: { item } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { item } = Astro.props as { item: EventItem };
|
const { item } = Astro.props as { item: EventItem };
|
||||||
|
const imageSrc = resolveEventImageSource(item.realimage);
|
||||||
|
const imageAlt = item.title;
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={item.title} description={item.description}>
|
<BaseLayout title={item.title} description={item.description}>
|
||||||
<article class="container prose">
|
<article class="container prose">
|
||||||
<p class="meta">{formatDateTime(item.start_datetime)}</p>
|
<p class="meta">{formatDateTime(item.start_datetime)}</p>
|
||||||
<h1 class="section-title">{item.title}</h1>
|
<h1 class="section-title">{item.title}</h1>
|
||||||
|
{imageSrc && <p><img src={imageSrc} alt={imageAlt} loading="lazy" /></p>}
|
||||||
<p>{item.description}</p>
|
<p>{item.description}</p>
|
||||||
{item.location_text && <p><strong>Location:</strong> {item.location_text}</p>}
|
{item.location_text && <p><strong>Location:</strong> {item.location_text}</p>}
|
||||||
{item.registration_link && <p><a class="button primary" href={item.registration_link}>Register</a></p>}
|
{item.registration_link && <p><a class="button primary" href={item.registration_link}>Register</a></p>}
|
||||||
|
|||||||
Reference in New Issue
Block a user