Files
dark-lord/app/vendor/[slug]/page.tsx
drjones 78a071ba02 Harden onion boot flow and deepen site surfaces
Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation.

Made-with: Cursor
2026-04-07 21:35:52 -07:00

79 lines
3.4 KiB
TypeScript

import Link from "next/link";
import { notFound } from "next/navigation";
import { VendorShelfRow } from "@/components/shop/VendorShelfRow";
import { shopProductsForSeller } from "@/lib/shopCatalog";
import { SHOP_SELLERS, getSellerBySlug } from "@/lib/shopSellers";
export function generateStaticParams() {
return SHOP_SELLERS.map((s) => ({ slug: s.slug }));
}
type Props = { params: Promise<{ slug: string }> };
export default async function VendorProfilePage({ params }: Props) {
const { slug } = await params;
const v = getSellerBySlug(slug);
if (!v) notFound();
const stock = shopProductsForSeller(v.id);
return (
<div className="min-h-screen bg-[#050302] text-[#f5f0e8]">
<header className="border-b border-orange-950/60 bg-[#0a0705]">
<div className="mx-auto max-w-4xl px-4 py-10">
<nav className="mb-6 flex flex-wrap gap-2 font-mono text-[11px] text-orange-300/60">
<Link href="/vendors" className="hover:text-orange-100">
Vendor hall
</Link>
<span className="text-orange-900">/</span>
<Link href="/market" className="hover:text-orange-100">
Catalog
</Link>
<span className="text-orange-900">/</span>
<Link href="/" className="hover:text-orange-100">
Hub
</Link>
</nav>
<div className="flex flex-wrap items-baseline gap-3">
<h1 className="font-orbitron text-3xl font-black text-orange-50 md:text-4xl">{v.handle}</h1>
<span className="rounded-full border border-orange-500/40 bg-orange-500/10 px-3 py-0.5 font-mono text-xs text-orange-200">
since {v.since}
</span>
</div>
<p className="mt-2 font-mono text-sm text-orange-400/90">{v.tagline}</p>
<p className="mt-4 max-w-2xl text-sm leading-relaxed text-orange-100/75">{v.bio}</p>
<dl className="mt-6 grid gap-3 font-mono text-xs sm:grid-cols-4">
<div className="rounded border border-orange-900/40 bg-black/30 px-3 py-2">
<dt className="text-orange-500/60">Rating</dt>
<dd className="text-orange-100"> {v.rating.toFixed(2)}</dd>
</div>
<div className="rounded border border-orange-900/40 bg-black/30 px-3 py-2">
<dt className="text-orange-500/60">Lore sales</dt>
<dd className="text-orange-100">{v.completedSales.toLocaleString()}</dd>
</div>
<div className="rounded border border-orange-900/40 bg-black/30 px-3 py-2">
<dt className="text-orange-500/60">Typical reply</dt>
<dd className="text-orange-100">~{v.responseMins}m</dd>
</div>
<div className="rounded border border-orange-900/40 bg-black/30 px-3 py-2">
<dt className="text-orange-500/60">Focus</dt>
<dd className="text-orange-100">{v.specialty}</dd>
</div>
</dl>
</div>
</header>
<main className="mx-auto max-w-4xl px-4 py-10">
<h2 className="font-mono text-[11px] font-bold uppercase tracking-[0.3em] text-orange-500/70">
Listings on this stall · {stock.length}
</h2>
<ul className="mt-6 space-y-4">
{stock.map((p) => (
<VendorShelfRow key={p.id} product={p} />
))}
</ul>
</main>
</div>
);
}