From f96079f63179e1680853556b86fb11e001c02faa Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 16:55:20 +0000 Subject: [PATCH] Add an All makes page to the Workshop Every make newest first with its craft, filterable by craft, linked as See all makes from Recently finished. Makes without a craft now link here instead of the Workshop page. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx --- services/admin/src/sitepages.ts | 1 + services/site/src/lib/site.ts | 2 +- services/site/src/pages/workshop/index.astro | 8 + services/site/src/pages/workshop/makes.astro | 206 +++++++++++++++++++ 4 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 services/site/src/pages/workshop/makes.astro diff --git a/services/admin/src/sitepages.ts b/services/admin/src/sitepages.ts index 68ca9a2..66d56cd 100644 --- a/services/admin/src/sitepages.ts +++ b/services/admin/src/sitepages.ts @@ -22,6 +22,7 @@ export const sitePages: SitePage[] = [ { page: "/work", name: "Work", feeds: ["post", "experience"] }, { page: "/resume", name: "Resume", feeds: ["experience", "skills", "education", "site-settings"] }, { page: "/workshop", name: "Workshop", feeds: ["craft", "make", "station", "tool"] }, + { page: "/workshop/makes", name: "All makes", feeds: ["make"] }, { page: "/library", name: "Library", feeds: ["library-item"] }, { page: "/library/shelf", name: "Shelf", feeds: ["board-game"] }, { page: "/tabletop", name: "Tabletop", feeds: ["tabletop-system", "campaign", "card-game", "deck"] }, diff --git a/services/site/src/lib/site.ts b/services/site/src/lib/site.ts index b40481d..1cca7de 100644 --- a/services/site/src/lib/site.ts +++ b/services/site/src/lib/site.ts @@ -87,7 +87,7 @@ export class SiteIndex { return `/workshop/${n.slug}`; case "make": { const craft = this.byName(d.craft as string); - return craft ? `/workshop/${craft.slug}#${n.slug}` : `/workshop#${n.slug}`; + return craft ? `/workshop/${craft.slug}#${n.slug}` : `/workshop/makes#${n.slug}`; } case "station": case "tool": diff --git a/services/site/src/pages/workshop/index.astro b/services/site/src/pages/workshop/index.astro index 91d1f0d..75b9494 100644 --- a/services/site/src/pages/workshop/index.astro +++ b/services/site/src/pages/workshop/index.astro @@ -146,6 +146,9 @@ const nowItems: NowItem[] = statusesFor(s, "/workshop").map((st) => { { recent.length > 0 && ( + + See all {allMakes.length} makes +
    {recent.map((m) => { const found = s.byName(m.data.craft); @@ -406,6 +409,11 @@ const nowItems: NowItem[] = statusesFor(s, "/workshop").map((st) => { align-self: flex-start; } + .all { + font-size: 14px; + white-space: nowrap; + } + /* Sword rack */ .rack { margin-top: 40px; diff --git a/services/site/src/pages/workshop/makes.astro b/services/site/src/pages/workshop/makes.astro new file mode 100644 index 0000000..4f120bf --- /dev/null +++ b/services/site/src/pages/workshop/makes.astro @@ -0,0 +1,206 @@ +--- +import Chip from "@gk/ui/components/Chip.astro"; +import FilterGroup from "@gk/ui/components/FilterGroup.astro"; +import PageShell from "@gk/ui/components/PageShell.astro"; +import StarChartArt from "@gk/ui/components/StarChartArt.astro"; +import { pageSeals } from "@gk/ui/components/seals.ts"; +import CtaBand from "../../components/world/CtaBand.astro"; +import WorldSection from "../../components/world/WorldSection.astro"; +import Button from "@gk/ui/components/Button.astro"; +import type { Note } from "../../lib/content.ts"; +import { plural, site } from "../../lib/page.ts"; +import { formatDate } from "../../lib/site.ts"; +import { byDateDesc, byOrder, craftSeal, makePhotos } from "../../lib/world.ts"; + +const s = await site(); +const text = s.pageText("/workshop/makes"); +const intro = s.render(text?.body); + +const craftOf = (m: Note<"make">) => { + const found = s.byName(m.data.craft); + return found?.type === "craft" ? (found as Note<"craft">) : undefined; +}; +// Newest first; makes without a finish date follow, still in a stable order. +const makes = byDateDesc(s.all("make")).sort((a, b) => Number(!!b.data.date) - Number(!!a.data.date)); +const crafts = byOrder(s.all("craft")).filter((c) => makes.some((m) => craftOf(m)?.path === c.path)); +const loose = makes.some((m) => !craftOf(m)); +const pills = + crafts.length + (loose ? 1 : 0) >= 2 + ? [{ label: "All", value: "", active: true }, ...crafts.map((c) => ({ label: c.title, value: c.slug })), ...(loose ? [{ label: "Other", value: "-" }] : [])] + : []; +--- + + +
    Workshop / Makes
    +

    {text?.title ?? "All makes"}

    +

    {text?.data.lede ?? "Everything I have made in the Workshop, newest first."}

    +
    + + {intro &&
    } + + + {pills.length > 0 && } + { + makes.length > 0 ? ( +
      + {makes.map((m) => { + const craft = craftOf(m); + const photos = makePhotos(m); + const log = s.backlinks(m, { type: "post" })[0]; + return ( +
    • + + + {craft && ( + + {craft.title} + + )} +

      {craft ? {m.title} : m.title}

      + {m.data.blurb && {m.data.blurb}} + {(m.data.date || log) && ( + + {m.data.date && } + {log && Build log} + + )} +
      +
    • + ); + })} +
    + ) : ( +

    Nothing finished yet.

    + ) + } +
    + + + + + + + + + +