"use client"; import { useMemo, useState, useEffect } from "react"; import { useSearchParams, useRouter } from "next/navigation"; import { CATEGORIES, PARTS } from "@/data/gunbuilderParts"; import type { CategoryId, Part } from "@/types/gunbuilder"; import { CategoryColumn } from "@/components/CategoryColumn"; type BuildState = Partial>; // categoryId -> partId const STORAGE_KEY = "gunbuilder-build-state"; export default function GunbuilderPage() { const searchParams = useSearchParams(); const router = useRouter(); const [build, setBuild] = useState(() => { // Initialize from localStorage if available if (typeof window !== "undefined") { const stored = localStorage.getItem(STORAGE_KEY); if (stored) { try { return JSON.parse(stored); } catch { return {}; } } } return {}; }); // Handle URL query parameter for part selection useEffect(() => { const selectParam = searchParams.get("select"); if (selectParam) { const [categoryId, partId] = selectParam.split(":"); if (categoryId && partId && CATEGORIES.some((c) => c.id === categoryId)) { setBuild((prev) => { const updated = { ...prev, [categoryId]: partId, }; // Persist to localStorage localStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); return updated; }); // Remove query param from URL router.replace("/gunbuilder", { scroll: false }); } } }, [searchParams, router]); // Persist build state to localStorage whenever it changes useEffect(() => { if (typeof window !== "undefined") { localStorage.setItem(STORAGE_KEY, JSON.stringify(build)); } }, [build]); const partsByCategory: Record = useMemo(() => { const grouped = {} as Record; for (const category of CATEGORIES) { grouped[category.id] = PARTS.filter( (p) => p.categoryId === category.id, ); } return grouped; }, []); const selectedParts: Part[] = useMemo(() => { return Object.entries(build) .map(([categoryId, partId]) => PARTS.find((p) => p.id === partId && p.categoryId === categoryId), ) .filter(Boolean) as Part[]; }, [build]); const totalPrice = useMemo( () => selectedParts.reduce((sum, p) => sum + p.price, 0), [selectedParts], ); const handleSelectPart = (categoryId: CategoryId, partId: string) => { setBuild((prev) => ({ ...prev, [categoryId]: partId, })); }; return (
{/* Header */}

Shadow Standard

Gunbuilder Prototype

Choose one part per category to assemble an AR-15 build. Prices and links are mock data for now—but the flow is close to what the real tool will be.

Current build total
${totalPrice.toFixed(2)}
{selectedParts.length} / {CATEGORIES.length} categories filled
{/* Layout */}
{/* Categories/parts */}
{CATEGORIES.map((category) => (
handleSelectPart(category.id, partId) } />
))}
{/* Build Summary */}
); }