This commit is contained in:
2026-05-12 11:44:31 -04:00
parent 290ff0bc1e
commit ed1293933f
4 changed files with 53 additions and 17 deletions
+2
View File
@@ -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:
+8 -3
View File
@@ -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) => {
const detailHref = event.slug ? `/events/${event.slug}/` : undefined;
return (
<article class="card"> <article class="card">
<div class="split-grid" style="align-items:start;"> <div class="split-grid" style="align-items:start;">
<div> <div>
<p class="pill">{event.is_featured ? 'Featured' : 'Event'}</p> <p class="pill">{event.is_featured ? 'Featured' : 'Event'}</p>
<h3>{event.title}</h3> <h3>{detailHref ? <a href={detailHref}>{event.title}</a> : event.title}</h3>
<p>{event.description}</p> <p>{event.description}</p>
</div> </div>
<div> <div>
<p class="meta">{formatDateTime(event.start_datetime)}</p> <p class="meta">{formatDateTime(event.start_datetime)}</p>
{event.location_text && <p>{event.location_text}</p>} {event.location_text && <p>{event.location_text}</p>}
{detailHref && <p><a class="button primary" href={detailHref}>View event</a></p>}
{event.registration_link && ( {event.registration_link && (
<p><a class="button secondary" href={event.registration_link}>Register</a></p> <p><a class="button secondary" href={event.registration_link}>Register</a></p>
)} )}
</div> </div>
</div> </div>
</article> </article>
)) );
})
) : ( ) : (
<article class="card"> <article class="card">
<h3>No events published</h3> <h3>No events published</h3>
+1
View File
@@ -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[];
+28
View File
@@ -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>}