mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-08 04:08:24 +00:00
Phase 5: every page of the site, the resume PDF and RSS
Landing, About, Now, Resume (with a generated PDF), Work and case studies, Inquiries and the sent page, Library and the Shelf, Workshop and craft pages, Tabletop, Blog with topics and posts, RSS, the Store, product lines, the order form and the 404, all rendered from the content service's notes. Schema: experience previousRoles, skills stack core items, page stats, make tags and deck favorite. Icon names from notes map to brand icons in one place, and HTML comments are dropped when Markdown renders. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
---
|
||||
/**
|
||||
* The order request form: lines that can take an order now, the chosen
|
||||
* line's options, quantity, details, notes, contact and the terms. When no
|
||||
* category takes orders, or every open line is full, a notice shows instead.
|
||||
*/
|
||||
import Button from "@gk/ui/components/Button.astro";
|
||||
import Notice from "@gk/ui/components/Notice.astro";
|
||||
import PageShell from "@gk/ui/components/PageShell.astro";
|
||||
import Star from "@gk/ui/components/Star.astro";
|
||||
import TickScale from "@gk/ui/components/TickScale.astro";
|
||||
import Breadcrumb from "../../components/store/Breadcrumb.astro";
|
||||
import LineStatus from "../../components/store/LineStatus.astro";
|
||||
import OrderForm from "../../components/store/OrderForm.astro";
|
||||
import { site } from "../../lib/page.ts";
|
||||
import { formatDate } from "../../lib/site.ts";
|
||||
import { canOrder, channelOf, storeState } from "../../lib/store.ts";
|
||||
|
||||
const s = await site();
|
||||
const st = storeState(s);
|
||||
const selected = Astro.url.searchParams.get("line") ?? undefined;
|
||||
const orderable = st.lines.filter((l) => canOrder(l, st));
|
||||
const selling = st.lines.filter((l) => channelOf(l) === "here");
|
||||
const shown = orderable.length ? orderable : selling;
|
||||
const turnarounds = [...new Set(st.groups.map(([c]) => st.category(c).turnaround).filter((t): t is string => !!t))];
|
||||
const reopens = st.closed.filter((c) => c.reopens).map((c) => `${c.name} reopens ${formatDate(c.reopens)}.`);
|
||||
---
|
||||
<PageShell title="Order request" family="store" current="store" description="Send an order request for something from the Store.">
|
||||
<section class="intro" aria-labelledby="order-h1">
|
||||
<Breadcrumb here="Order request" />
|
||||
<h1 id="order-h1">Order request</h1>
|
||||
<p class="lede">Send a request and I will confirm the details and the total with you. No payment is taken through the site.</p>
|
||||
</section>
|
||||
|
||||
<div class="layout">
|
||||
<div class="main">
|
||||
{
|
||||
orderable.length > 0 ? (
|
||||
<OrderForm lines={orderable} selected={selected} storeTerms={st.terms} />
|
||||
) : (
|
||||
<div class="closed">
|
||||
{st.anyOpen ? (
|
||||
<Notice title="All order slots are taken right now.">Slots reopen as current orders finish.</Notice>
|
||||
) : (
|
||||
<Notice title="Orders currently closed.">{reopens.join(" ")}</Notice>
|
||||
)}
|
||||
<p>{st.settings?.capacityNote}</p>
|
||||
<div class="actions">
|
||||
<Button href="/store">Back to the Store</Button>
|
||||
<Button variant="secondary" href="/inquiries">Something custom? Start an inquiry</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
<aside class="side" aria-label="Order status">
|
||||
{shown.map((l) => <LineStatus line={l} />)}
|
||||
{
|
||||
(turnarounds.length > 0 || st.settings?.capacityNote) && (
|
||||
<div class="know">
|
||||
<span class="know-head">
|
||||
<Star size={11} />
|
||||
<span>Good to know</span>
|
||||
</span>
|
||||
<TickScale width={160} height={10} count={24} />
|
||||
{turnarounds.map((t) => <span>{t}</span>)}
|
||||
{orderable.length > 0 && st.settings?.capacityNote && <span>{st.settings.capacityNote}</span>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{orderable.length > 0 && <a href="/inquiries" class="gk-text inq">Something custom? Start an inquiry</a>}
|
||||
</aside>
|
||||
</div>
|
||||
</PageShell>
|
||||
|
||||
<style>
|
||||
.intro {
|
||||
padding: 36px 0 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: clamp(32px, 5vw, 44px);
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.lede {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
color: var(--gk-soft);
|
||||
max-width: 64ch;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.layout {
|
||||
padding: 16px 0 64px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 32px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.main {
|
||||
flex: 3 1 600px;
|
||||
min-width: 0;
|
||||
}
|
||||
.closed {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
padding: 32px;
|
||||
border-radius: var(--gk-radius);
|
||||
background: var(--gk-midnight);
|
||||
border: 1px solid rgba(201, 162, 74, 0.55);
|
||||
}
|
||||
.closed :global(.gk-note) {
|
||||
font-size: 15px;
|
||||
}
|
||||
.closed p {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
color: var(--gk-soft);
|
||||
}
|
||||
.closed p:empty {
|
||||
display: none;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
.side {
|
||||
flex: 1 1 280px;
|
||||
max-width: 360px;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
.know {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 18px 20px;
|
||||
border-radius: var(--gk-radius);
|
||||
background: var(--gk-midnight);
|
||||
border: 1px solid var(--gk-lines);
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: var(--gk-soft);
|
||||
}
|
||||
.know-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.3em;
|
||||
font-weight: 600;
|
||||
color: var(--gk-gold-bright);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.inq {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
align-self: flex-start;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
.side {
|
||||
max-width: none;
|
||||
}
|
||||
.closed {
|
||||
padding: 22px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user