refactor: replace MarketOffers component with MarketExample in home page

Renamed imported component from MarketOffers to MarketExample and updated its usage in the home page layout. Also removed rarity badge display from ItemCard to align with simplified design.
Related to component refactoring for consistency.
This commit is contained in:
Evandro Fonseca Junior committed 2025-10-30 19:17:46 -03:00
1 parent b8426efbf0
commit e641138887
6 files changed
+201 -42

No files matched your search

+2 -2
View File
@@ -4,7 +4,7 @@ import { EscrowExplanation } from "@/components/sections/escrow-explanation";
import { HeroSection } from "@/components/sections/hero-section"; import { HeroSection } from "@/components/sections/hero-section";
import { HowItWorks } from "@/components/sections/how-it-works"; import { HowItWorks } from "@/components/sections/how-it-works";
import { FeaturedItems } from "@/components/sections/featured-items"; import { FeaturedItems } from "@/components/sections/featured-items";
import { MarketOffers } from "@/components/sections/market-offers"; import { MarketExample } from "@/components/sections/market-example";
import { MarketStats } from "@/components/sections/market-stats"; import { MarketStats } from "@/components/sections/market-stats";
import { DonationFooterCard } from "@/components/donation-footer-card"; import { DonationFooterCard } from "@/components/donation-footer-card";
@@ -17,7 +17,7 @@ export default function Home() {
<HeroSection /> <HeroSection />
<HowItWorks /> <HowItWorks />
<FeaturedItems /> <FeaturedItems />
<MarketOffers /> <MarketExample />
<MarketStats /> <MarketStats />
</main> </main>
<EscrowExplanation /> <EscrowExplanation />
-15
View File
@@ -283,21 +283,6 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
<MagicCard className="p-0 overflow-hidden rounded-xl border border-border/50 hover:border-primary/30 transition-all duration-300 hover:scale-[1.02] hover:shadow-xl"> <MagicCard className="p-0 overflow-hidden rounded-xl border border-border/50 hover:border-primary/30 transition-all duration-300 hover:scale-[1.02] hover:shadow-xl">
{/* Header com ícone e badge de raridade */} {/* Header com ícone e badge de raridade */}
<div className="relative aspect-square bg-linear-to-br from-background to-muted p-6"> <div className="relative aspect-square bg-linear-to-br from-background to-muted p-6">
{/* Badge de raridade com glow (apenas em modo market) */}
{mode === "market" && (
<Badge
className={`${
rarityColors[item.rarity]
} text-white absolute top-3 left-3 z-20 shadow-lg ${getRarityGlow(
item.rarity
)} ${item.rarity === "legendary" ? "animate-pulse" : ""} ${
item.rarity === "epic" ? "animate-pulse" : ""
}`}
>
{item.rarity}
</Badge>
)}
{/* Botão de favorito */} {/* Botão de favorito */}
<Button <Button
variant="ghost" variant="ghost"
+164
View File
@@ -0,0 +1,164 @@
"use client";
import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
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>
);
}
+25 -25
View File
@@ -3,22 +3,22 @@ import { TibiaItem, MarketOffer } from "@/types/item";
export const featuredItems: TibiaItem[] = [ export const featuredItems: TibiaItem[] = [
{ {
id: "1", id: "1",
name: "Armor of Fire", name: "Ornate Chestplate",
image: "/items/armor-of-fire.png", image: "/api/images?path=data/images/armaduras/ornate_chestplate.gif",
alt: "Armor of Fire - Armadura lendária de Tibia com proteção contra fogo +10", alt: "Ornate Chestplate - Armadura lendária de Tibia nível 300",
category: "armor", category: "armor",
rarity: "legendary", rarity: "legendary",
stats: { armor: 16, weight: 120 }, stats: { armor: 18, weight: 185 },
requirements: { level: 200, vocation: "Knight" }, requirements: { level: 300, vocation: "Knight" },
protections: { fire: 10 }, protections: { fire: 5, ice: 5 },
price: { buy: 2500000, sell: 2200000, bid: 2350000 }, price: { buy: 8500000, sell: 8200000, bid: 8350000 },
priceHistory: { highest: 2800000, lowest: 2000000, average: 2350000 }, priceHistory: { highest: 9000000, lowest: 8000000, average: 8400000 },
dropLocation: "Fire Dragon Lair", dropLocation: "Ornate Chest",
}, },
{ {
id: "2", id: "2",
name: "Demon Helmet", name: "Demon Helmet",
image: "/items/demon-helmet.png", image: "/api/images?path=data/images/capacetes/demon_helmet.gif",
alt: "Demon Helmet - Capacete épico de Tibia nível 100", alt: "Demon Helmet - Capacete épico de Tibia nível 100",
category: "helmet", category: "helmet",
rarity: "epic", rarity: "epic",
@@ -31,7 +31,7 @@ export const featuredItems: TibiaItem[] = [
{ {
id: "3", id: "3",
name: "Vampire Shield", name: "Vampire Shield",
image: "/items/vampire-shield.png", image: "/api/images?path=data/images/escudos/vampire_shield.gif",
alt: "Vampire Shield - Escudo épico de Tibia com defesa 38", alt: "Vampire Shield - Escudo épico de Tibia com defesa 38",
category: "shield", category: "shield",
rarity: "epic", rarity: "epic",
@@ -44,7 +44,7 @@ export const featuredItems: TibiaItem[] = [
{ {
id: "4", id: "4",
name: "Zaoan Helmet", name: "Zaoan Helmet",
image: "/items/zaoan-helmet.png", image: "/api/images?path=data/images/capacetes/zaoan_helmet.gif",
alt: "Zaoan Helmet - Capacete raro de Tibia nível 80", alt: "Zaoan Helmet - Capacete raro de Tibia nível 80",
category: "helmet", category: "helmet",
rarity: "rare", rarity: "rare",
@@ -57,7 +57,7 @@ export const featuredItems: TibiaItem[] = [
{ {
id: "5", id: "5",
name: "Magic Sword", name: "Magic Sword",
image: "/items/magic-sword.png", image: "/api/images?path=data/images/espadas/magic_sword.gif",
alt: "Magic Sword - Espada rara de Tibia nível 75", alt: "Magic Sword - Espada rara de Tibia nível 75",
category: "weapon", category: "weapon",
rarity: "rare", rarity: "rare",
@@ -70,7 +70,7 @@ export const featuredItems: TibiaItem[] = [
{ {
id: "6", id: "6",
name: "Demonbone Amulet", name: "Demonbone Amulet",
image: "/items/demonbone-amulet.png", image: "/api/images?path=data/images/amuletos/demonbone_amulet.gif",
alt: "Demonbone Amulet - Amuleto épico de Tibia com proteção contra fogo", alt: "Demonbone Amulet - Amuleto épico de Tibia com proteção contra fogo",
category: "amulet", category: "amulet",
rarity: "epic", rarity: "epic",
@@ -82,22 +82,22 @@ export const featuredItems: TibiaItem[] = [
}, },
{ {
id: "7", id: "7",
name: "Ornate Chestplate", name: "Dragon Shield",
image: "/items/ornate-chestplate.png", image: "/api/images?path=data/images/escudos/dragon_shield.gif",
alt: "Ornate Chestplate - Armadura lendária de Tibia nível 300", alt: "Dragon Shield - Escudo lendário de Tibia",
category: "armor", category: "shield",
rarity: "legendary", rarity: "legendary",
stats: { armor: 18, weight: 185 }, stats: { defense: 45, weight: 55 },
requirements: { level: 300, vocation: "Knight" }, requirements: { level: 200, vocation: "Knight" },
protections: { fire: 5, ice: 5 }, protections: { fire: 10, energy: 5 },
price: { buy: 8500000, sell: 8200000, bid: 8350000 }, price: { buy: 1500000, sell: 1400000, bid: 1450000 },
priceHistory: { highest: 9000000, lowest: 8000000, average: 8400000 }, priceHistory: { highest: 1600000, lowest: 1350000, average: 1475000 },
dropLocation: "Ornate Chest", dropLocation: "Dragon Lairs",
}, },
{ {
id: "8", id: "8",
name: "Ultimate Health Potion", name: "Ultimate Health Potion",
image: "/items/uhp.png", image: "/api/images?path=data/images/liquidos/ultimate_health_potion.gif",
alt: "Ultimate Health Potion - Poção de saúde máxima de Tibia", alt: "Ultimate Health Potion - Poção de saúde máxima de Tibia",
category: "potion", category: "potion",
rarity: "common", rarity: "common",
+5
View File
@@ -173,6 +173,11 @@
"stats": "Statistics", "stats": "Statistics",
"viewDetails": "View Details", "viewDetails": "View Details",
"buyNow": "Buy Now" "buyNow": "Buy Now"
},
"marketExample": {
"title": "Market Examples",
"subtitle": "See real Tibia items with updated prices",
"errorTitle": "Error Loading Items"
} }
}, },
"underConstruction": { "underConstruction": {
+5
View File
@@ -173,6 +173,11 @@
"stats": "Estatísticas", "stats": "Estatísticas",
"viewDetails": "Ver Detalhes", "viewDetails": "Ver Detalhes",
"buyNow": "Comprar Agora" "buyNow": "Comprar Agora"
},
"marketExample": {
"title": "Exemplos do Market",
"subtitle": "Veja itens reais do Tibia com preços atualizados",
"errorTitle": "Erro ao Carregar Itens"
} }
}, },
"underConstruction": { "underConstruction": {