cleaning up api calls and the builder page
This commit is contained in:
@@ -52,7 +52,7 @@ type GunbuilderProductFromApi = {
|
||||
platform: string;
|
||||
partRole: string;
|
||||
price: number | null;
|
||||
mainImageUrl: string | null;
|
||||
imageUrl: string | null;
|
||||
buyUrl: string | null;
|
||||
inStock?: boolean | null;
|
||||
};
|
||||
@@ -150,7 +150,7 @@ export default function PartsBrowseClient(props: {
|
||||
|
||||
const search = new URLSearchParams();
|
||||
search.set("platform", effectivePlatform);
|
||||
search.append("partRoles", partRole);
|
||||
search.append("partRole", partRole);
|
||||
|
||||
// server paging (0-based)
|
||||
search.set("page", String(currentPage - 1));
|
||||
@@ -162,22 +162,13 @@ export default function PartsBrowseClient(props: {
|
||||
|
||||
// sort mapping
|
||||
switch (sortBy) {
|
||||
case "price-asc":
|
||||
search.set("sort", "price,asc");
|
||||
break;
|
||||
case "price-desc":
|
||||
search.set("sort", "price,desc");
|
||||
break;
|
||||
case "brand-asc":
|
||||
search.set("sort", "brand,asc");
|
||||
break;
|
||||
case "relevance":
|
||||
default:
|
||||
search.set("sort", "updatedAt,desc");
|
||||
break;
|
||||
}
|
||||
|
||||
const res = await fetch(`${API_BASE_URL}/api/v1/products?${search.toString()}`, {
|
||||
const res = await fetch(`${API_BASE_URL}/api/v1/catalog/options?${search.toString()}`, {
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
@@ -194,7 +185,7 @@ export default function PartsBrowseClient(props: {
|
||||
platform: p.platform,
|
||||
partRole: p.partRole,
|
||||
price: p.price ?? 0,
|
||||
imageUrl: p.mainImageUrl ?? undefined,
|
||||
imageUrl: p.imageUrl ?? undefined,
|
||||
buyUrl: p.buyUrl ?? undefined,
|
||||
inStock: p.inStock ?? true,
|
||||
}))
|
||||
@@ -277,44 +268,7 @@ export default function PartsBrowseClient(props: {
|
||||
});
|
||||
}, [priceBounds.min, priceBounds.max]);
|
||||
|
||||
const filteredParts = useMemo(() => {
|
||||
let result = [...parts];
|
||||
|
||||
if (priceRange.min != null)
|
||||
result = result.filter((p) => p.price >= priceRange.min!);
|
||||
if (priceRange.max != null)
|
||||
result = result.filter((p) => p.price <= priceRange.max!);
|
||||
|
||||
if (brandFilter.length)
|
||||
result = result.filter((p) => brandFilter.includes(p.brand));
|
||||
|
||||
if (inStockOnly) result = result.filter((p) => p.inStock ?? true);
|
||||
|
||||
const q = searchQuery.toLowerCase().trim();
|
||||
if (q)
|
||||
result = result.filter(
|
||||
(p) =>
|
||||
p.name.toLowerCase().includes(q) || p.brand.toLowerCase().includes(q)
|
||||
);
|
||||
|
||||
switch (sortBy) {
|
||||
case "price-asc":
|
||||
result.sort((a, b) => a.price - b.price);
|
||||
break;
|
||||
case "price-desc":
|
||||
result.sort((a, b) => b.price - a.price);
|
||||
break;
|
||||
case "brand-asc":
|
||||
result.sort((a, b) => a.brand.localeCompare(b.brand));
|
||||
break;
|
||||
case "relevance":
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [parts, brandFilter, sortBy, searchQuery, priceRange, inStockOnly]);
|
||||
|
||||
const filteredParts = useMemo(() => parts, [parts]);
|
||||
const totalPages = Math.max(1, serverTotalPages);
|
||||
const paginatedParts = filteredParts; // filteredParts should become just parts now (see below)
|
||||
|
||||
@@ -338,7 +292,7 @@ export default function PartsBrowseClient(props: {
|
||||
|
||||
if (!categoryId) {
|
||||
alert(
|
||||
`No CategoryId mapping found for role "${partRole}". Add it to catalogMappings.`
|
||||
`No Category mapping found for role "${partRole}". Add it to catalogMappings.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -453,7 +407,7 @@ export default function PartsBrowseClient(props: {
|
||||
{!loading && !error && (
|
||||
<SortBar
|
||||
visibleRange={visibleRange}
|
||||
totalCount={filteredParts.length}
|
||||
totalCount={serverTotalElements}
|
||||
searchQuery={searchQuery}
|
||||
setSearchQuery={setSearchQuery}
|
||||
sortBy={sortBy}
|
||||
@@ -467,7 +421,7 @@ export default function PartsBrowseClient(props: {
|
||||
</p>
|
||||
) : error ? (
|
||||
<p className="py-8 text-center text-sm text-red-400">{error}</p>
|
||||
) : filteredParts.length === 0 ? (
|
||||
) : serverTotalElements === 0 ? (
|
||||
<p className="py-8 text-center text-sm text-zinc-500">
|
||||
No parts found for this role yet.
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user