"use client";
import {
ArrowDown,
ArrowUp,
DollarSign,
ShoppingCart,
TrendingUp,
Users,
} from "lucide-react";
import { useTranslations } from "next-intl";
import { Area, AreaChart, ResponsiveContainer } from "recharts";
import { Badge } from "@/components/ui/badge";
import { NumberTicker } from "@/components/ui/number-ticker";
import { buyOffers, sellOffers } from "@/lib/mock-data";
interface StatData {
icon: typeof ShoppingCart;
value: number;
label: string;
change: number; // percentual
trend: "up" | "down";
sparklineData: number[]; // 7 pontos
iconColor: string;
iconBg: string;
description: string;
lastUpdated: string;
}
// Componente Mini Sparkline
function MiniSparkline({ data, color }: { data: number[]; color: string }) {
const chartData = data.map((value, index) => ({
value,
index,
}));
return (
);
}
// Componente StatCard individual
function StatCard({ stat }: { stat: StatData }) {
const TrendIcon = stat.trend === "up" ? ArrowUp : ArrowDown;
const isPositive = stat.trend === "up";
return (
{/* Ícone com círculo colorido */}
{/* Número principal */}
{/* Badge de variação */}
{stat.change}%
{/* Label e descrição */}
{stat.label}
{stat.description}
{/* Mini Sparkline */}
{/* Timestamp */}
{stat.lastUpdated}
);
}
export function MarketStats() {
const t = useTranslations("home.stats");
// Calcular volume total baseado nos dados mock
const _calculateTotalVolume = () => {
const buyVolume = buyOffers.reduce(
(sum, offer) => sum + offer.price * offer.quantity,
0,
);
const sellVolume = sellOffers.reduce(
(sum, offer) => sum + offer.price * offer.quantity,
0,
);
return Math.round((buyVolume + sellVolume) / 1000); // Dividir por 1000 para número mais legível
};
const stats: StatData[] = [
{
icon: ShoppingCart,
value: 1542,
label: t("activeOffers"),
change: 8.5,
trend: "up",
sparklineData: [1200, 1300, 1400, 1350, 1450, 1500, 1542],
iconColor: "text-orange-500",
iconBg: "bg-orange-500/10",
description: "esta semana",
lastUpdated: `${t("updated")} 5 ${t("minutes")}`,
},
{
icon: TrendingUp,
value: 8763,
label: t("itemsSold"),
change: 15.3,
trend: "up",
sparklineData: [7200, 7500, 7800, 8000, 8200, 8500, 8763],
iconColor: "text-green-500",
iconBg: "bg-green-500/10",
description: `${t("averagePerDay")}: 292 ${t("salesPerDay")}`,
lastUpdated: `${t("updated")} 5 ${t("minutes")}`,
},
{
icon: Users,
value: 3421,
label: t("users"),
change: 22.1,
trend: "up",
sparklineData: [3100, 3200, 3250, 3300, 3350, 3400, 3421],
iconColor: "text-blue-500",
iconBg: "bg-blue-500/10",
description: `${t("onlineNow")}: 847 ${t("traders")}`,
lastUpdated: `${t("updated")} 2 ${t("minutes")}`,
},
{
icon: DollarSign,
value: 208,
label: t("totalVolume"),
change: 18.7,
trend: "up",
sparklineData: [180, 200, 220, 240, 260, 280, 300],
iconColor: "text-purple-500",
iconBg: "bg-purple-500/10",
description: "em gold pieces",
lastUpdated: `${t("today")}: 12.5M gp`,
},
];
return (
{t("title")}
{stats.map((stat, index) => (
))}
);
}