subnav and other stuff
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { CATEGORIES } from "@/data/gunbuilderParts";
|
||||
import type { Category } from "@/types/gunbuilder";
|
||||
|
||||
type BuilderNavProps = {
|
||||
activeCategoryId?: string | null;
|
||||
};
|
||||
|
||||
// Helper to group categories for the dropdowns
|
||||
function groupCategories(group: "lower" | "upper" | "accessories"): Category[] {
|
||||
return CATEGORIES.filter((c) => c.group === group);
|
||||
}
|
||||
|
||||
export function BuilderNav({ activeCategoryId }: BuilderNavProps) {
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const lower = groupCategories("lower");
|
||||
const upper = groupCategories("upper");
|
||||
const accessories = groupCategories("accessories");
|
||||
|
||||
const currentCategory =
|
||||
activeCategoryId ?? searchParams.get("category") ?? undefined;
|
||||
|
||||
const baseHref = "/gunbuilder";
|
||||
|
||||
const renderDropdown = (label: string, items: Category[]) => {
|
||||
if (!items.length) return null;
|
||||
|
||||
return (
|
||||
<div className="relative group">
|
||||
<button
|
||||
type="button"
|
||||
className={`inline-flex items-center gap-1 font-medium tracking-wide transition-colors uppercase text-[11px] ${
|
||||
items.some(cat => cat.id === currentCategory)
|
||||
? "text-white"
|
||||
: "text-neutral-200 hover:text-white"
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
<span className="text-[9px]">▾</span>
|
||||
</button>
|
||||
|
||||
<div className="invisible opacity-0 group-hover:visible group-hover:opacity-100 transition-all absolute left-0 mt-2 rounded-md border border-neutral-800 bg-black/95 shadow-xl z-40 min-w-[220px]">
|
||||
<ul className="py-2 text-sm">
|
||||
{items.map((cat) => {
|
||||
const isActive = currentCategory === cat.id;
|
||||
return (
|
||||
<li key={cat.id}>
|
||||
<Link
|
||||
href={`${baseHref}/${cat.id}`}
|
||||
className={[
|
||||
"block w-full px-3 py-1.5 text-left text-sm transition-colors",
|
||||
isActive
|
||||
? "bg-neutral-800 text-white"
|
||||
: "text-neutral-300 hover:bg-neutral-800 hover:text-white",
|
||||
].join(" ")}
|
||||
>
|
||||
{cat.name}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-6xl mx-auto w-full"> {/* ← aligns with topnav */}
|
||||
<nav className="flex items-center gap-6 border-b border-neutral-900 px-6 py-3 text-sm bg-black/95 backdrop-blur-sm">
|
||||
{/* Primary builder link */}
|
||||
<Link
|
||||
href={baseHref}
|
||||
className="font-semibold text-neutral-100 hover:text-white tracking-[0.25em] uppercase text-[11px]"
|
||||
>
|
||||
Builder
|
||||
</Link>
|
||||
|
||||
{renderDropdown("Lower Parts", lower)}
|
||||
{renderDropdown("Upper Parts", upper)}
|
||||
{renderDropdown("Accessories", accessories)}
|
||||
|
||||
<Link
|
||||
href="/builds"
|
||||
className="font-medium text-neutral-300 hover:text-white tracking-[0.25em] uppercase text-[11px]"
|
||||
>
|
||||
Builds
|
||||
</Link>
|
||||
|
||||
{/* Right → Current filter */}
|
||||
{currentCategory && (
|
||||
<div className="ml-auto flex items-center gap-2 text-neutral-400 text-xs">
|
||||
<span className="uppercase tracking-wide text-[10px]">Viewing</span>
|
||||
<span className="font-medium text-neutral-100">
|
||||
{CATEGORIES.find((c) => c.id === currentCategory)?.name ??
|
||||
currentCategory}
|
||||
</span>
|
||||
<Link
|
||||
href={baseHref}
|
||||
className="rounded border border-neutral-700 px-2 py-0.5 text-[10px] uppercase tracking-wide hover:bg-neutral-800 hover:text-white"
|
||||
>
|
||||
Clear
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BuilderNav;
|
||||
@@ -9,6 +9,22 @@ export function TopNav() {
|
||||
|
||||
return (
|
||||
<header className="border-b border-zinc-800 bg-black/95 backdrop-blur">
|
||||
<div className="border-b border-amber-500/20 bg-amber-500/5">
|
||||
<div className="mx-auto flex max-w-6xl flex-col gap-1 px-4 py-2 text-[0.75rem] text-amber-100 md:flex-row md:items-center md:justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="rounded-sm bg-amber-500/20 px-2 py-0.5 text-[0.65rem] font-semibold uppercase tracking-[0.18em] text-amber-300">
|
||||
Early Access Beta
|
||||
</span>
|
||||
<span className="hidden text-amber-100/90 md:inline">
|
||||
You're using an early-access prototype of The Armory. Data,
|
||||
pricing, and available parts are still evolving.
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-amber-100/90 md:hidden">
|
||||
Early-access prototype. Data and pricing may change.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto flex max-w-6xl items-center justify-between px-4 py-2">
|
||||
{/* Brand / Home link */}
|
||||
<Link
|
||||
|
||||
Reference in New Issue
Block a user