feat(item-card): add 'market'/'catalog' mode prop with defensive price checks
Introduces optional `mode` prop ("market"/"catalog") to conditionally render components like rarity badges. Adds defensive checks for missing price data and priceHistory properties to prevent runtime errors. New icons `Badge` and `Boxes` imported from lucide-react.
This commit is contained in:
1 parent
29ba5aece0
commit
44d7f8ce81
21 files changed
+1181
-714
No files matched your search
@@ -0,0 +1,69 @@
|
||||
import { NextRequest } from "next/server";
|
||||
import { searchItems } from "@/lib/items-db";
|
||||
import { buildPublicItemImageUrl } from "@/lib/item-images";
|
||||
|
||||
function parseArray(param: string | null): string[] {
|
||||
if (!param) return [];
|
||||
// Suporta formatos: comma-separated (a,b) ou múltiplos parâmetros já combinados
|
||||
return param
|
||||
.split(",")
|
||||
.map((v) => v.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const q = searchParams.get("q") || undefined;
|
||||
const categories = parseArray(searchParams.get("category"));
|
||||
const rarities = parseArray(searchParams.get("rarity"));
|
||||
const sortParam = (searchParams.get("sort") || "name") as
|
||||
| "name"
|
||||
| "price-asc"
|
||||
| "price-desc"
|
||||
| "rarity"
|
||||
| "recent";
|
||||
const page = Number(searchParams.get("page") || "1");
|
||||
const pageSize = Number(searchParams.get("pageSize") || "24");
|
||||
|
||||
const { items, total } = searchItems({
|
||||
q,
|
||||
categories,
|
||||
rarities,
|
||||
sort: sortParam,
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
|
||||
// Enriquecer com URL pública de imagem quando possível
|
||||
const itemsWithImage = items.map((it: any) => {
|
||||
const img = (it.image || "").toString();
|
||||
// Preferir URL absoluta do banco para teste
|
||||
if (/^https?:\/\//i.test(img)) {
|
||||
return { ...it, image: img };
|
||||
}
|
||||
if (img.startsWith("data/")) {
|
||||
return { ...it, image: `/api/images?path=${encodeURIComponent(img)}` };
|
||||
}
|
||||
const categoryEn = (it.category || "other").toString();
|
||||
return { ...it, image: buildPublicItemImageUrl(categoryEn, img) };
|
||||
});
|
||||
|
||||
const totalPages = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||
return Response.json(
|
||||
{ items: itemsWithImage, page, pageSize, total, totalPages },
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error: any) {
|
||||
console.error("[api/items] Erro:", error?.message, error?.stack);
|
||||
return Response.json(
|
||||
{
|
||||
error: "Falha ao consultar itens",
|
||||
message: error?.message || "Erro desconhecido",
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user