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,73 @@
|
||||
import Header from "@/components/Header";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import LibraryClient from "./LibraryClient";
|
||||
|
||||
interface Item {
|
||||
id: string;
|
||||
name: string;
|
||||
category: string;
|
||||
image?: string;
|
||||
rarity?: string;
|
||||
npcPrice?: number;
|
||||
price?: { buy: number; sell: number };
|
||||
priceHistory?: { highest: number; lowest: number; average: number };
|
||||
stats?: any;
|
||||
requirements?: any;
|
||||
protections?: any;
|
||||
}
|
||||
|
||||
async function fetchItems(params: URLSearchParams) {
|
||||
const qs = params.toString();
|
||||
const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL ?? ""}/api/items?${qs}`, {
|
||||
// Em ambiente server, revalidação curta para manter leve
|
||||
next: { revalidate: 15 },
|
||||
});
|
||||
if (!res.ok) {
|
||||
return { items: [], total: 0, page: 1, pageSize: 24, totalPages: 1 };
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations({ locale, namespace: "underConstruction" });
|
||||
return {
|
||||
title: t("market.title"),
|
||||
description: t("market.description"),
|
||||
};
|
||||
}
|
||||
|
||||
export default async function LibraryPage({ params, searchParams }: {
|
||||
params: Promise<{ locale: string }>;
|
||||
searchParams?: Promise<Record<string, string | string[] | undefined>>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
const sp = (await searchParams) ?? {};
|
||||
const initial = new URLSearchParams();
|
||||
if (typeof sp.q === "string") initial.set("q", sp.q);
|
||||
if (typeof sp.sort === "string") initial.set("sort", sp.sort);
|
||||
if (typeof sp.page === "string") initial.set("page", sp.page);
|
||||
if (typeof sp.pageSize === "string") initial.set("pageSize", sp.pageSize);
|
||||
if (typeof sp.category === "string") initial.set("category", sp.category);
|
||||
if (typeof sp.rarity === "string") initial.set("rarity", sp.rarity);
|
||||
|
||||
const data = await fetchItems(initial);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen">
|
||||
<Header />
|
||||
<main className="container mx-auto px-4 py-8 space-y-8">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-2xl font-bold">Biblioteca de Itens</h1>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{data.total} {data.total === 1 ? "item" : "itens"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LibraryClient initial={data} />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user