fixed part role calls and some other stuff
This commit is contained in:
@@ -5,6 +5,7 @@ import Link from "next/link";
|
||||
import { useParams, useRouter, useSearchParams } from "next/navigation";
|
||||
import { CATEGORIES } from "@/data/gunbuilderParts";
|
||||
import type { CategoryId, Part } from "@/types/gunbuilder";
|
||||
import { CATEGORY_TO_PART_ROLES } from "@/data/partRoleMappings";
|
||||
|
||||
type ViewMode = "card" | "list";
|
||||
|
||||
@@ -44,9 +45,21 @@ const slugify = (str: string) =>
|
||||
.replace(/[^a-z0-9]+/g, "-")
|
||||
.replace(/(^-|-$)/g, "");
|
||||
|
||||
const normalizeRole = (role: string) => role.trim().toLowerCase().replace(/_/g, "-");
|
||||
|
||||
function getNormalizedPartRolesForCategory(categoryId: string): string[] {
|
||||
const roles = (CATEGORY_TO_PART_ROLES as any)[categoryId] as string[] | undefined;
|
||||
if (!roles || roles.length === 0) return [];
|
||||
return Array.from(new Set(roles.map(normalizeRole)));
|
||||
}
|
||||
|
||||
export default function CategoryPage() {
|
||||
const params = useParams();
|
||||
const categoryId = params.categoryId as CategoryId;
|
||||
const partRoles = useMemo(
|
||||
() => getNormalizedPartRolesForCategory(String(categoryId)),
|
||||
[categoryId]
|
||||
);
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
@@ -102,6 +115,11 @@ export default function CategoryPage() {
|
||||
const search = new URLSearchParams();
|
||||
search.set("platform", platform);
|
||||
|
||||
// ✅ Scope results to this category's backend roles
|
||||
for (const r of partRoles) {
|
||||
search.append("partRoles", r);
|
||||
}
|
||||
|
||||
const url = `${API_BASE_URL}/api/products?${search.toString()}`;
|
||||
|
||||
const res = await fetch(url, { signal: controller.signal });
|
||||
@@ -136,7 +154,7 @@ export default function CategoryPage() {
|
||||
fetchCategoryParts();
|
||||
|
||||
return () => controller.abort();
|
||||
}, [categoryId, platform]);
|
||||
}, [categoryId, platform, partRoles]);
|
||||
|
||||
// persist build to localStorage whenever it changes
|
||||
useEffect(() => {
|
||||
|
||||
@@ -155,7 +155,9 @@ export default function GunbuilderPage() {
|
||||
|
||||
const [scopedRes, universalRes] = await Promise.all([
|
||||
fetch(scopedUrl, { signal: controller.signal }),
|
||||
fetch(universalUrl, { signal: controller.signal }).catch(() => null as any),
|
||||
fetch(universalUrl, { signal: controller.signal }).catch(
|
||||
() => null as any
|
||||
),
|
||||
]);
|
||||
|
||||
if (!scopedRes || !scopedRes.ok) {
|
||||
@@ -174,12 +176,20 @@ export default function GunbuilderPage() {
|
||||
const normalize = (data: GunbuilderProductFromApi[]): Part[] =>
|
||||
data
|
||||
.map((p): Part | null => {
|
||||
const categoryId = PART_ROLE_TO_CATEGORY[p.partRole];
|
||||
const normalizedRole = (p.partRole ?? "")
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/_/g, "-");
|
||||
|
||||
const categoryId = PART_ROLE_TO_CATEGORY[normalizedRole];
|
||||
if (!categoryId) return null;
|
||||
|
||||
// Only keep truly-universal categories from the universal feed
|
||||
// so we don't accidentally mix platforms for platform-scoped parts.
|
||||
if (data === universalData && !UNIVERSAL_CATEGORIES.has(categoryId)) {
|
||||
if (
|
||||
data === universalData &&
|
||||
!UNIVERSAL_CATEGORIES.has(categoryId)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -471,13 +481,15 @@ export default function GunbuilderPage() {
|
||||
onChange={(e) => {
|
||||
const next = e.target.value as (typeof PLATFORMS)[number];
|
||||
setPlatform(next);
|
||||
|
||||
|
||||
// Keep URL in sync so navigation + refresh preserve platform
|
||||
const qp = new URLSearchParams(searchParams.toString());
|
||||
qp.set("platform", next);
|
||||
qp.delete("select");
|
||||
|
||||
router.replace(`/builder?${qp.toString()}`, { scroll: false });
|
||||
|
||||
router.replace(`/builder?${qp.toString()}`, {
|
||||
scroll: false,
|
||||
});
|
||||
}}
|
||||
className="rounded-md border border-zinc-700 bg-zinc-900 px-2 py-1 text-xs text-zinc-100 focus:outline-none focus:ring-1 focus:ring-amber-400"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user