159 lines
4.8 KiB
TypeScript
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>
|
|
);
|
|
}
|