Files
2025-11-11 03:08:36 -03:00

159 lines
4.8 KiB
TypeScript

"use client";
import { useTranslations } from "next-intl";
import { useEffect, useState } from "react";
import { ItemCard } from "@/components/item-card";
import { BlurFade } from "@/components/ui/blur-fade";
import { Skeleton } from "@/components/ui/skeleton";
interface MarketItem {
id: string;
name: string;
image: string;
category: string;
level?: number;
weight?: number;
rarity?: string;
price?: {
buy: number;
sell: number;
};
priceHistory?: {
highest: number;
lowest: number;
average: number;
};
}
export function MarketExample() {
const t = useTranslations("home.marketExample");
const [items, setItems] = useState<MarketItem[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
async function fetchItems() {
try {
setIsLoading(true);
// Buscar mix de categorias para variedade visual
const categories = ["weapon", "armor", "helmet"];
const response = await fetch(
`/api/items?category=${categories.join(",")}&pageSize=8&sort=name`,
);
if (!response.ok) {
throw new Error("Falha ao carregar itens");
}
const data = await response.json();
const fetchedItems = data.items || [];
// Enriquecer com preços mockados e raridades
const enrichedItems = fetchedItems.map((item: any, index: number) => {
const basePrice = Math.floor(Math.random() * 100000) + 10000;
const buyPrice = basePrice;
const sellPrice = Math.floor(basePrice * 0.85);
const average = basePrice;
const highest = Math.floor(average * 1.3);
const lowest = Math.floor(average * 0.7);
return {
...item,
// Garantir ID único para evitar duplicação de keys
id: `${item.id}-${index}`,
price: {
buy: buyPrice,
sell: sellPrice,
},
priceHistory: {
highest,
lowest,
average,
},
rarity:
item.rarity ||
(["common", "uncommon", "rare", "epic"] as const)[
Math.floor(Math.random() * 4)
],
};
});
setItems(enrichedItems);
setError(null);
} catch (err) {
console.error("Erro ao buscar itens:", err);
setError("Não foi possível carregar os itens");
} finally {
setIsLoading(false);
}
}
fetchItems();
}, []);
// Skeleton para loading
const LoadingSkeleton = () => (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{Array.from({ length: 8 }).map((_, index) => (
<div key={index} className="space-y-4">
<Skeleton className="h-48 w-full rounded-xl" />
<div className="space-y-2">
<Skeleton className="h-6 w-3/4" />
<Skeleton className="h-4 w-1/2" />
<Skeleton className="h-4 w-1/3" />
</div>
<div className="space-y-2">
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-2/3" />
</div>
</div>
))}
</div>
);
return (
<section className="py-20 bg-muted/30">
<div className="container">
<BlurFade delay={0.2}>
<div className="text-center mb-16">
<h2 className="text-4xl font-bold mb-4">{t("title")}</h2>
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
{t("subtitle")}
</p>
</div>
</BlurFade>
{/* Grid de itens */}
{isLoading ? (
<LoadingSkeleton />
) : error ? (
<div className="text-center py-12">
<div className="text-6xl mb-4">⚠️</div>
<h3 className="text-xl font-semibold mb-2">{t("errorTitle")}</h3>
<p className="text-muted-foreground">{error}</p>
</div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{items.map((item, index) => (
<BlurFade key={item.id} delay={0.2 + index * 0.05}>
<ItemCard item={item as any} mode="market" />
</BlurFade>
))}
</div>
)}
{/* Mensagem quando não há itens */}
{!isLoading && !error && items.length === 0 && (
<div className="text-center py-12">
<div className="text-6xl mb-4">📦</div>
<h3 className="text-xl font-semibold mb-2">
Nenhum item encontrado
</h3>
<p className="text-muted-foreground">Tente novamente mais tarde</p>
</div>
)}
</div>
</section>
);
}