diff --git a/src/lib/format.ts b/src/lib/format.ts index 7126bc1..5405d12 100644 Binary files a/src/lib/format.ts and b/src/lib/format.ts differ diff --git a/src/pages/dispatches/[slug].astro b/src/pages/dispatches/[slug].astro new file mode 100644 index 0000000..d70fbc6 --- /dev/null +++ b/src/pages/dispatches/[slug].astro @@ -0,0 +1,258 @@ +--- +import AppLayout from '../../layouts/AppLayout.astro'; +import Avatar from '../../components/Avatar.astro'; +import { getDispatchById, getAdjacentDispatches } from '../../lib/db'; +import { + parseDispatchSlug, dispatchSlug, dispatchKindLabel, + dispatchKindPigment, roleLabel, +} from '../../lib/format'; +import { renderMd } from '../../lib/markdown'; + +const user = Astro.locals.user; +const slugParam = Astro.params.slug ?? ''; +const id = parseDispatchSlug(slugParam); + +if (!id) return Astro.redirect('/dispatches'); + +const d = getDispatchById(id); +if (!d || d.status !== 'published') return Astro.redirect('/dispatches'); + +// Canonical-redirect when the slug changes after a rename — id is the authority +const canonical = dispatchSlug(d); +if (slugParam !== canonical) return Astro.redirect(`/dispatches/${canonical}`); + +const { prev, next } = getAdjacentDispatches(d.id); + +function parseUtc(s: string): Date { + if (/T.*[Zz]$/.test(s) || /[+-]\d{2}:?\d{2}$/.test(s)) return new Date(s); + return new Date(s.replace(' ', 'T') + 'Z'); +} +function fmt(iso: string): string { + return new Intl.DateTimeFormat('en-GB', { + day: 'numeric', month: 'long', year: 'numeric', timeZone: 'Europe/Copenhagen', + }).format(parseUtc(iso)); +} + +const bodyHtml = renderMd(d.body); +--- + +
+ + ← All dispatches + +
+
+ + {dispatchKindLabel(d.kind)} + + +
+ +

{d.title}

+ + +
+ +
+
+ + diff --git a/src/pages/dispatches/index.astro b/src/pages/dispatches/index.astro new file mode 100644 index 0000000..459cfda --- /dev/null +++ b/src/pages/dispatches/index.astro @@ -0,0 +1,182 @@ +--- +import AppLayout from '../../layouts/AppLayout.astro'; +import Avatar from '../../components/Avatar.astro'; +import { getLatestPublishedDispatches } from '../../lib/db'; +import { + dispatchSlug, dispatchKindLabel, dispatchKindPigment, + dispatchExcerptParas, roleLabel, +} from '../../lib/format'; + +const user = Astro.locals.user; +const dispatches = getLatestPublishedDispatches(200); + +function parseUtc(s: string): Date { + if (/T.*[Zz]$/.test(s) || /[+-]\d{2}:?\d{2}$/.test(s)) return new Date(s); + return new Date(s.replace(' ', 'T') + 'Z'); +} +function fmt(iso: string): string { + return new Intl.DateTimeFormat('en-GB', { + day: 'numeric', month: 'long', year: 'numeric', timeZone: 'Europe/Copenhagen', + }).format(parseUtc(iso)); +} +--- + +
+ +
+

Dispatches

+

Notes from the studio.

+

Decisions, half-built ideas, and things we've changed our mind about.

+
+ + {dispatches.length === 0 ? ( +

Nothing posted yet.

+ ) : ( + + )} + +
+
+ +