Files
com.gregkilmer.www/services/site/src/pages/store/order/sent.astro
T
Claude 151bed230a Match the site to the approved designs
Denser star field, the page nebula, a favicon package, the filament banner
without its box, the About portrait, Kashi and tea photos and Scorpius, the
Store's own header, a header logo glow, a resume PDF that fills its page,
one divider on the Library and Shelf, star-chart art for coverless
favorites, Shelf Players, Play time and blog filters with a Show all fold,
make kind pills on craft pages, and full-width closing bands.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-12 03:33:15 +00:00

206 lines
5.5 KiB
Plaintext

---
/**
* The confirmation after an order request. /api/orders sets the short-lived
* `gk-order` cookie (URL-encoded JSON: name, email, line, rows) before it
* redirects here; the page shows it once and clears it. Without the cookie
* the page still reads correctly.
*/
import Button from "@gk/ui/components/Button.astro";
import PageShell from "@gk/ui/components/PageShell.astro";
import Star from "@gk/ui/components/Star.astro";
import TickRing from "@gk/ui/components/TickRing.astro";
import TickScale from "@gk/ui/components/TickScale.astro";
import Breadcrumb from "../../../components/store/Breadcrumb.astro";
import { parseOrderSent } from "../../../lib/forms.ts";
import { site } from "../../../lib/page.ts";
import { storeNav, storeState } from "../../../lib/store.ts";
const sent = parseOrderSent(Astro.cookies.get("gk-order")?.value);
if (sent) Astro.cookies.delete("gk-order", { path: "/" });
Astro.response.headers.set("Cache-Control", "private, no-store");
const s = await site().catch(() => null);
const replyTime = s?.settings()?.replyTime ?? "a few days";
const st = s ? storeState(s) : undefined;
const line = sent?.lineSlug ? st?.lines.find((l) => l.slug === sent.lineSlug) : undefined;
const turnaround = line ? st?.category(line.data.category).turnaround : undefined;
const rows = [
...(sent?.line ? [{ label: "Line", value: sent.line }] : []),
...(sent?.rows ?? []),
...(sent?.email ? [{ label: "Reply to", value: sent.email }] : []),
];
const firstName = sent?.name?.split(/\s+/)[0];
const steps = [
{ title: "I check the request", text: "The details, the options and my queue." },
{ title: "I confirm with you", text: "The total and the timing, by email. No payment is taken through the site." },
{ title: "I start once you say yes", text: turnaround ?? "Nothing is made until we agree." },
];
---
<PageShell title="Order request sent" family="store" current="store" store={st ? storeNav(st, "/store/order") : undefined} description="Your order request is on its way.">
<meta slot="head" name="robots" content="noindex" />
<section class="intro" aria-labelledby="sent-h1">
<Breadcrumb here="Request sent" />
<h1 id="sent-h1">Your request is in</h1>
<p class="lede">Thanks{firstName ? `, ${firstName}` : ""}. I read every order request myself and reply within {replyTime}.</p>
</section>
<div class="layout">
<div class="main">
<ol class="steps" aria-label="What happens next">
{
steps.map((st, i) => (
<li>
<TickRing size={36}>{i + 1}</TickRing>
<span class="step-text">
<span class="step-title">{st.title}</span>
<span class="step-detail">{st.text}</span>
</span>
</li>
))
}
</ol>
<div class="actions">
<Button href="/store">Back to the Store</Button>
<Button variant="secondary" href="/inquiries">Something custom? Start an inquiry</Button>
</div>
</div>
{
rows.length > 0 && (
<aside class="sent" aria-labelledby="sent-heading">
<h2 id="sent-heading" class="kicker">
<Star size={11} />
What you sent
</h2>
<TickScale width={150} height={10} count={30} class="ticks" />
<dl>
{rows.map((r) => (
<div class="row">
<dt>{r.label}</dt>
<dd>{r.value}</dd>
</div>
))}
</dl>
</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 480px;
min-width: 0;
display: flex;
flex-direction: column;
gap: 20px;
}
.steps {
margin: 0;
padding: 0;
list-style: none;
border-bottom: 1px solid var(--gk-lines);
}
.steps li {
display: flex;
gap: 14px;
align-items: flex-start;
padding: 14px 0;
border-top: 1px solid var(--gk-lines);
font-size: 13px;
}
.step-text {
display: flex;
flex-direction: column;
gap: 3px;
}
.step-title {
font-weight: 700;
font-size: 15px;
}
.step-detail {
font-size: 14px;
color: var(--gk-muted);
line-height: 1.5;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.sent {
flex: 1 1 300px;
max-width: 420px;
min-width: 0;
padding: 24px;
border-radius: var(--gk-radius);
background: var(--gk-midnight);
border: 1px solid rgba(201, 162, 74, 0.55);
}
.kicker {
margin: 0 0 8px;
display: flex;
align-items: center;
gap: 8px;
font-family: var(--gk-font-body);
font-size: 11px;
letter-spacing: 0.3em;
font-weight: 600;
color: var(--gk-gold-bright);
text-transform: uppercase;
}
.sent :global(.ticks) {
margin: -4px 0 2px;
}
dl {
margin: 8px 0 0;
}
.row {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 10px 0;
border-top: 1px solid var(--gk-lines);
font-size: 14px;
}
dt {
color: var(--gk-muted);
}
dd {
margin: 0;
font-weight: 600;
text-align: right;
overflow-wrap: anywhere;
}
@media (max-width: 700px) {
.sent {
max-width: none;
}
}
</style>