fixed platform selector and part selector

This commit is contained in:
2025-12-11 16:27:28 -05:00
parent b26dcb947e
commit 777618f684
3 changed files with 498 additions and 438 deletions
File diff suppressed because it is too large Load Diff
+42 -4
View File
@@ -87,7 +87,16 @@ export default function GunbuilderPage() {
const [parts, setParts] = useState<Part[]>([]); const [parts, setParts] = useState<Part[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [platform, setPlatform] = useState<(typeof PLATFORMS)[number]>("AR-15"); const isValidPlatform = (
value: string | null
): value is (typeof PLATFORMS)[number] =>
!!value && (PLATFORMS as readonly string[]).includes(value);
const [platform, setPlatform] = useState<(typeof PLATFORMS)[number]>(() => {
if (typeof window === "undefined") return "AR-15";
const initial = new URLSearchParams(window.location.search).get("platform");
return isValidPlatform(initial) ? initial : "AR-15";
});
const [build, setBuild] = useState<BuildState>(() => { const [build, setBuild] = useState<BuildState>(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const stored = localStorage.getItem(STORAGE_KEY); const stored = localStorage.getItem(STORAGE_KEY);
@@ -189,11 +198,26 @@ export default function GunbuilderPage() {
return updated; return updated;
}); });
router.replace("/builder", { scroll: false }); const qp = searchParams.get("platform");
const nextPlatform = isValidPlatform(qp) ? qp : platform;
router.replace(
`/builder?platform=${encodeURIComponent(nextPlatform)}`,
{
scroll: false,
}
);
} }
} }
}, [searchParams, router]); }, [searchParams, router]);
useEffect(() => {
const qp = searchParams.get("platform");
if (isValidPlatform(qp) && qp !== platform) {
setPlatform(qp);
}
}, [searchParams, platform]);
// Persist build state to localStorage whenever it changes // Persist build state to localStorage whenever it changes
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
@@ -695,10 +719,24 @@ export default function GunbuilderPage() {
<Link <Link
href={{ href={{
pathname: `/builder/${category.id}`, pathname: `/builder/${category.id}`,
query: { platform }, query: platform ? { platform } : {},
}} }}
className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border border-zinc-700 bg-zinc-900/70 px-3 py-1.5 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors"
> >
Choose a Part <svg
className="w-3.5 h-3.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 4v16m8-8H4"
/>
</svg>
<span>Choose a Part</span>
</Link> </Link>
) : ( ) : (
<span className="text-[0.7rem] text-zinc-600"> <span className="text-[0.7rem] text-zinc-600">
+11 -3
View File
@@ -9,6 +9,7 @@ interface CategoryColumnProps {
parts: Part[]; parts: Part[];
selectedPartId?: string; selectedPartId?: string;
onSelectPart: (partId: string) => void; onSelectPart: (partId: string) => void;
platform?: string;
} }
export function CategoryColumn({ export function CategoryColumn({
@@ -16,6 +17,7 @@ export function CategoryColumn({
parts, parts,
selectedPartId, selectedPartId,
onSelectPart, onSelectPart,
platform,
}: CategoryColumnProps) { }: CategoryColumnProps) {
// Show selected part if available, otherwise show placeholder // Show selected part if available, otherwise show placeholder
const displayedPart = selectedPartId const displayedPart = selectedPartId
@@ -37,8 +39,11 @@ export function CategoryColumn({
<div className="w-full border border-zinc-700 rounded-md p-3 mb-2 flex items-center justify-between gap-3"> <div className="w-full border border-zinc-700 rounded-md p-3 mb-2 flex items-center justify-between gap-3">
<p className="text-sm text-zinc-500">No part selected</p> <p className="text-sm text-zinc-500">No part selected</p>
<Link <Link
href={`/builder/${category.id}`} href={{
className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-900/60 px-3 py-1.5 text-xs font-medium text-zinc-200 hover:bg-zinc-800 hover:border-zinc-500 transition-colors" pathname: `/builder/${category.id}`,
query: platform ? { platform } : {},
}}
className="inline-flex w-full items-center justify-center rounded-md border border-zinc-700 bg-zinc-900 px-4 py-2 text-xs font-semibold text-zinc-100 hover:bg-zinc-800 hover:border-zinc-600 transition-colors"
> >
<svg <svg
className="w-4 h-4" className="w-4 h-4"
@@ -68,7 +73,10 @@ export function CategoryColumn({
</div> </div>
{parts.length >= 1 && ( {parts.length >= 1 && (
<Link <Link
href={`/builder/${category.id}`} href={{
pathname: `/builder/${category.id}`,
query: platform ? { platform } : {},
}}
className="mt-2 w-full rounded-md border border-zinc-700 bg-zinc-900/50 px-3 py-2 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center" className="mt-2 w-full rounded-md border border-zinc-700 bg-zinc-900/50 px-3 py-2 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center"
> >
View All ({parts.length}) View All ({parts.length})