--- import 'katex/dist/katex.min.css'; import 'highlight.js/styles/atom-one-dark.css'; import Layout from '../../layouts/Layout.astro'; import DeletePostButton from '../../components/react/DeletePostButton'; import { renderMarkdown } from '../../lib/markdown'; const { slug } = Astro.params; const API_URL = (typeof process !== 'undefined' ? process.env.PUBLIC_API_URL : import.meta.env.PUBLIC_API_URL) || 'http://localhost:3000'; interface CoverImage { url: string; alt: string; w?: number; h?: number } interface PostNeighbor { slug: string; title?: string; } interface PostDetail { slug: string; date: string; content: string; title?: string; summary?: string; tags: string[]; draft: boolean; reading_time: number; cover_image?: CoverImage; image_count: number; prev?: PostNeighbor; next?: PostNeighbor; dimensions?: Record; } function formatDate(d: string) { return new Date(d).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } function formatSlug(s: string) { if (!s) return ''; return s.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '); } let post: PostDetail | null = null; let html = ''; let error = ''; try { const postRes = await fetch(`${API_URL}/api/posts/${encodeURIComponent(slug ?? '')}`); if (postRes.ok) { post = await postRes.json(); html = renderMarkdown(post!.content, post!.dimensions); } else { error = 'Work not found in the catalogue'; } } catch (e) { const cause = (e as any)?.cause; error = `Could not connect to backend at ${API_URL}: ${e instanceof Error ? e.message : String(e)}${cause ? ' (Cause: ' + (cause.message || cause.code || JSON.stringify(cause)) + ')' : ''}`; console.error(error); } const neighbors = { prev: post?.prev, next: post?.next, }; const isAdmin = Astro.cookies.get('admin_session')?.value === '1'; const displayTitle = post ? (post.title || formatSlug(post.slug)) : 'Work'; --- {post?.cover_image?.url && ( )} {error && (
Pardon —

{error}

← Return to the catalogue
)} {post && (
{/* Toolbar — exhibit nav */} {/* Plaque header */}

{displayTitle}

{formatDate(post.date)} {post.image_count > 0 && ( <> · {post.image_count} {post.image_count === 1 ? 'plate' : 'plates'} )}
{post.summary && (

{post.summary}

)} {post.draft && (
Sketch · unpublished
)} {post.tags?.length > 0 && (
{post.tags.map(tag => {tag})}
)}
{/* Body — works on paper */}
{(neighbors.prev || neighbors.next) && ( )}
)}