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
95 lines
4.0 KiB
TypeScript
95 lines
4.0 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useSearchParams } from "next/navigation";
|
|
import { Suspense } from "react";
|
|
|
|
const LANES: { id: string; label: string }[] = [
|
|
{ id: "goods", label: "Goods" },
|
|
{ id: "services", label: "Labor" },
|
|
{ id: "data", label: "Data" },
|
|
{ id: "open", label: "Open" },
|
|
];
|
|
|
|
function BarterPitChromeInner({ children }: { children: React.ReactNode }) {
|
|
const sp = useSearchParams();
|
|
const activeLane = sp.get("lane") ?? undefined;
|
|
|
|
return (
|
|
<div className="min-h-screen bg-[#030806] text-[#b8f5c6]">
|
|
<div
|
|
className="pointer-events-none fixed inset-0 z-0 opacity-[0.07]"
|
|
style={{
|
|
backgroundImage: `linear-gradient(rgba(57,255,20,0.08) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(57,255,20,0.05) 1px, transparent 1px)`,
|
|
backgroundSize: "48px 48px",
|
|
}}
|
|
/>
|
|
<div className="pointer-events-none fixed inset-0 z-0 bg-[radial-gradient(ellipse_at_top,_rgba(0,80,40,0.35),_transparent_55%)]" />
|
|
|
|
<header className="relative z-20 border-b border-[#0d2818] bg-[#050a07]/95 backdrop-blur-md">
|
|
<div className="mx-auto flex max-w-6xl flex-col gap-3 px-4 py-5 md:flex-row md:items-end md:justify-between">
|
|
<div>
|
|
<p className="font-mono text-[9px] uppercase tracking-[0.5em] text-[#39ff14]/55">unhosted barter mesh</p>
|
|
<h1 className="mt-1 bg-gradient-to-r from-[#7cfc9aad] to-[#39ff14] bg-clip-text font-mono text-2xl font-black tracking-tight text-transparent md:text-3xl">
|
|
ASH PIT
|
|
</h1>
|
|
<p className="mt-2 max-w-xl font-mono text-[11px] leading-relaxed text-[#6b9b78]/95">
|
|
Trading floor for <span className="text-[#9af0a8]">swap terms</span> — no cart, no spot book. Post what you have,
|
|
what you want, negotiate in-thread. Same session wallet as the hub when you need settlement.
|
|
</p>
|
|
</div>
|
|
<nav className="flex flex-wrap gap-2 font-mono text-[10px] uppercase tracking-wider">
|
|
<Link
|
|
href="/"
|
|
className="rounded border border-[#164024] bg-[#0a120d] px-3 py-2 text-[#8dcda0] hover:border-[#39ff14]/40"
|
|
>
|
|
Storefront
|
|
</Link>
|
|
<Link href="/exchange" className="rounded border border-[#164024] px-3 py-2 text-[#8dcda0] hover:border-[#39ff14]/40">
|
|
Gazette
|
|
</Link>
|
|
<Link href="/forum" className="rounded border border-[#164024] px-3 py-2 text-[#8dcda0] hover:border-[#39ff14]/40">
|
|
Forum
|
|
</Link>
|
|
<Link href="/checkout" className="rounded border border-[#39ff14]/35 bg-[#39ff14]/10 px-3 py-2 text-[#c8ffce] hover:bg-[#39ff14]/18">
|
|
Settlement
|
|
</Link>
|
|
</nav>
|
|
</div>
|
|
<div className="mx-auto flex max-w-6xl flex-wrap gap-1 border-t border-[#0d2818] px-4 py-2">
|
|
<Link
|
|
href="/barter"
|
|
className={`rounded px-2 py-1 font-mono text-[10px] uppercase ${
|
|
!activeLane ? "bg-[#39ff14]/20 text-[#c8ffce]" : "text-[#5a7d62] hover:text-[#9af0a8]"
|
|
}`}
|
|
>
|
|
All lanes
|
|
</Link>
|
|
{LANES.map((l) => (
|
|
<Link
|
|
key={l.id}
|
|
href={`/barter?lane=${l.id}`}
|
|
className={`rounded px-2 py-1 font-mono text-[10px] uppercase ${
|
|
activeLane === l.id ? "bg-[#39ff14]/20 text-[#c8ffce]" : "text-[#5a7d62] hover:text-[#9af0a8]"
|
|
}`}
|
|
>
|
|
{l.label}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</header>
|
|
|
|
<div className="relative z-10 mx-auto max-w-6xl px-4 py-10">{children}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function BarterPitChrome({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<Suspense fallback={<div className="min-h-screen bg-[#030806] pt-24 text-center font-mono text-sm text-[#5a7d62]">Loading…</div>}>
|
|
<BarterPitChromeInner>{children}</BarterPitChromeInner>
|
|
</Suspense>
|
|
);
|
|
}
|