style: clean up code formatting and remove trailing whitespace

refactor: reorganize imports and fix type imports
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-11 03:08:36 -03:00
1 parent d3704602fd
commit 47c04de6fe
232 files changed
+7140 -4798

No files matched your search

+173 -147
View File
@@ -1,45 +1,39 @@
"use client";
import { TibiaItem } from "@/types/item";
import { MagicCard } from "@/components/ui/magic-card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { PriceDisplay } from "@/components/ui/price-display";
import { useTranslations, useLocale } from "next-intl";
import {
TrendingUp,
TrendingDown,
Sword,
Shield,
Weight,
Heart,
Star,
ArrowDown,
ArrowUp,
Boxes,
Clock,
Coins,
ArrowUp,
ArrowDown,
Minus,
Zap,
Flame,
Snowflake,
Zap as Energy,
Skull,
Cross,
Badge as BadgeIcon,
Boxes,
Gem,
FlaskConical,
Wrench,
ScrollText,
Leaf,
Zap as Energy,
Flame,
FlaskConical,
Gem,
Heart,
Leaf,
Minus,
ScrollText,
Shield,
Skull,
Snowflake,
Star,
Sword,
TrendingDown,
TrendingUp,
Weight,
Wrench,
Zap,
} from "lucide-react";
import { useLocale, useTranslations } from "next-intl";
import { useEffect, useRef, useState } from "react";
import {
getRarityColor,
getRarityBgColor,
getRarityGlow,
} from "@/lib/currency-utils";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { MagicCard } from "@/components/ui/magic-card";
import { PriceDisplay } from "@/components/ui/price-display";
import { formatNumber } from "@/lib/utils/formatters";
import type { TibiaItem } from "@/types/item";
interface ItemCardProps {
item: TibiaItem;
@@ -50,7 +44,7 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
const t = useTranslations("home.item");
const locale = useLocale();
const [isFavorited, setIsFavorited] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [_isHovered, setIsHovered] = useState(false);
const formatVocation = (v: string | undefined): string | undefined => {
if (!v) return undefined;
let out = String(v);
@@ -64,14 +58,22 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
return out;
};
const ScrollRow = ({ children, ariaLabel }: { children: React.ReactNode; ariaLabel: string }) => {
const ScrollRow = ({
children,
ariaLabel,
}: {
children: React.ReactNode;
ariaLabel: string;
}) => {
const scrollerRef = useRef<HTMLDivElement | null>(null);
const contentRef = useRef<HTMLDivElement | null>(null);
const [canScrollLeft, setCanScrollLeft] = useState(false);
const [canScrollRight, setCanScrollRight] = useState(false);
const [_canScrollLeft, setCanScrollLeft] = useState(false);
const [_canScrollRight, setCanScrollRight] = useState(false);
const [isHovering, setIsHovering] = useState(false);
const autoScrollRef = useRef<number | null>(null);
const drag = useRef<{ active: boolean; startX: number; startLeft: number }>({ active: false, startX: 0, startLeft: 0 });
const drag = useRef<{ active: boolean; startX: number; startLeft: number }>(
{ active: false, startX: 0, startLeft: 0 },
);
const [isDragging, setIsDragging] = useState(false);
const updateButtons = () => {
@@ -114,9 +116,9 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
el.removeEventListener("mouseleave", onLeave);
ro.disconnect();
};
}, []);
}, [updateButtons]);
const scrollBy = (dx: number) => {
const _scrollBy = (dx: number) => {
const el = scrollerRef.current;
if (!el) return;
const base = contentRef.current?.offsetWidth || 0;
@@ -182,7 +184,9 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
if (!drag.current.active) return;
drag.current.active = false;
setIsDragging(false);
try { el.releasePointerCapture(e.pointerId); } catch {}
try {
el.releasePointerCapture(e.pointerId);
} catch {}
};
el.addEventListener("pointerdown", onPointerDown);
@@ -204,7 +208,7 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
ref={scrollerRef}
className={`overflow-x-auto no-scrollbar whitespace-nowrap pr-6 pl-6 select-none ${isDragging ? "cursor-grabbing" : "cursor-grab"}`}
style={{ scrollBehavior: "smooth" }}
>
>
<div ref={contentRef} className="inline-flex items-center gap-2">
{children}
{children}
@@ -213,10 +217,10 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
</div>
);
};
const [showAllDroppers, setShowAllDroppers] = useState(false);
const rarityColors = {
const [_showAllDroppers, _setShowAllDroppers] = useState(false);
const _rarityColors = {
common: "bg-gray-500",
uncommon: "bg-green-500",
rare: "bg-blue-500",
@@ -251,14 +255,20 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
(item as any).price.sell !== 0;
const priceDifference = hasPrice
? (((item as any).price.buy - (item as any).price.sell) /
(item as any).price.sell) * 100
(item as any).price.sell) *
100
: 0;
const isHotDeal = hasPrice && priceDifference > 20; // Hot deal se diferença > 20%
// Determinar tendência de preço
const getPriceTrend = () => {
const ph = (item as any).priceHistory;
if (!ph || typeof ph.highest !== "number" || typeof ph.lowest !== "number" || typeof ph.average !== "number") {
if (
!ph ||
typeof ph.highest !== "number" ||
typeof ph.lowest !== "number" ||
typeof ph.average !== "number"
) {
return "stable";
}
if (ph.highest > ph.average * 1.1) return "up";
@@ -273,8 +283,8 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
trend === "up"
? "text-green-500"
: trend === "down"
? "text-red-500"
: "text-gray-500";
? "text-red-500"
: "text-gray-500";
return (
<div
@@ -323,9 +333,7 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
/>
) : (
<div className="w-20 h-20 bg-muted/50 rounded-xl flex items-center justify-center text-3xl backdrop-blur-sm">
{typeof CategoryIcon === "string" ? (
null
) : (
{typeof CategoryIcon === "string" ? null : (
<CategoryIcon className="w-10 h-10" />
)}
</div>
@@ -352,7 +360,8 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
{(() => {
const catPt = (item as any).categoryPt as string | undefined;
const catEn = (item as any).category as string | undefined;
const catRaw = (catPt && String(catPt)) || (catEn && String(catEn)) || "";
const catRaw =
(catPt && String(catPt)) || (catEn && String(catEn)) || "";
const display = catRaw
? catRaw.charAt(0).toUpperCase() + catRaw.slice(1)
: "";
@@ -375,9 +384,7 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
{item.stats.attack && (
<div className="flex items-center gap-1.5 text-sm">
<Sword className="h-4 w-4 text-primary" />
<span className="font-medium">
{item.stats.attack} ATK
</span>
<span className="font-medium">{item.stats.attack} ATK</span>
</div>
)}
{item.stats.defense && (
@@ -391,21 +398,23 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
{item.stats.armor && (
<div className="flex items-center gap-1.5 text-sm">
<Shield className="h-4 w-4 text-primary" />
<span className="font-medium">
{item.stats.armor} ARM
</span>
<span className="font-medium">{item.stats.armor} ARM</span>
</div>
)}
{(item as any).volume && (
<div className="flex items-center gap-1.5 text-sm">
<Boxes className="h-4 w-4 text-primary" />
<span className="font-medium">Volume {(item as any).volume}</span>
<span className="font-medium">
Volume {(item as any).volume}
</span>
</div>
)}
{(item as any).bonus_de_skill && (
<div className="flex items-center gap-1.5 text-sm">
<Zap className="h-4 w-4 text-primary" />
<span className="font-medium">Skill +{(item as any).bonus_de_skill}</span>
<span className="font-medium">
Skill +{(item as any).bonus_de_skill}
</span>
</div>
)}
</div>
@@ -457,84 +466,91 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
</div>
)}
{(item as any).protecao && (() => {
const raw = String((item as any).protecao || "");
const tokens = raw
.split(",")
.map((s) => s.trim())
.filter(Boolean)
.filter((s) => !/^nenhum(a)?\.?$/i.test(s.trim()));
if (tokens.length === 0) return null;
return (
<ScrollRow ariaLabel="elemental protections">
{tokens.map((raw: string, idx: number) => {
const token = raw.trim();
const match = token.match(/^([A-Za-zçÇáÁéÉíÍóÓúÚãÃõÕ ]+)(.*)$/);
const type = (match?.[1] || token).trim().toLowerCase();
const value = (match?.[2] || "").trim();
let Icon: any = Shield;
let chipBg = "bg-amber-500/10";
let chipText = "text-amber-700";
switch (type) {
case "fire":
case "fogo":
Icon = Flame;
chipBg = "bg-red-500/10";
chipText = "text-red-600";
break;
case "ice":
case "gelo":
Icon = Snowflake;
chipBg = "bg-blue-500/10";
chipText = "text-blue-600";
break;
case "energy":
case "energia":
Icon = Energy;
chipBg = "bg-yellow-500/10";
chipText = "text-yellow-600";
break;
case "earth":
case "terra":
Icon = Leaf;
chipBg = "bg-green-500/10";
chipText = "text-green-600";
break;
case "death":
case "morte":
Icon = Skull;
chipBg = "bg-zinc-500/10";
chipText = "text-zinc-600";
break;
case "holy":
case "sagrado":
Icon = Cross;
chipBg = "bg-amber-500/10";
chipText = "text-amber-700";
break;
case "physical":
case "fisico":
Icon = Shield;
chipBg = "bg-slate-500/10";
chipText = "text-slate-600";
break;
default:
Icon = Shield;
chipBg = "bg-amber-500/10";
chipText = "text-amber-700";
}
const prettyType = type.charAt(0).toUpperCase() + type.slice(1);
const label = `${prettyType.replace("fisico", "Físico")}${value ? " " + value : ""}`;
return (
<div key={`${type}-${idx}`} className={`flex items-center gap-1 text-xs ${chipBg} ${chipText} px-2 py-1 rounded`}>
<Icon className="h-3 w-3" />
<span className="whitespace-nowrap">{label}</span>
</div>
);
})}
</ScrollRow>
);
})()}
{(item as any).protecao &&
(() => {
const raw = String((item as any).protecao || "");
const tokens = raw
.split(",")
.map((s) => s.trim())
.filter(Boolean)
.filter((s) => !/^nenhum(a)?\.?$/i.test(s.trim()));
if (tokens.length === 0) return null;
return (
<ScrollRow ariaLabel="elemental protections">
{tokens.map((raw: string, idx: number) => {
const token = raw.trim();
const match = token.match(
/^([A-Za-zçÇáÁéÉíÍóÓúÚãÃõÕ ]+)(.*)$/,
);
const type = (match?.[1] || token).trim().toLowerCase();
const value = (match?.[2] || "").trim();
let Icon: any = Shield;
let chipBg = "bg-amber-500/10";
let chipText = "text-amber-700";
switch (type) {
case "fire":
case "fogo":
Icon = Flame;
chipBg = "bg-red-500/10";
chipText = "text-red-600";
break;
case "ice":
case "gelo":
Icon = Snowflake;
chipBg = "bg-blue-500/10";
chipText = "text-blue-600";
break;
case "energy":
case "energia":
Icon = Energy;
chipBg = "bg-yellow-500/10";
chipText = "text-yellow-600";
break;
case "earth":
case "terra":
Icon = Leaf;
chipBg = "bg-green-500/10";
chipText = "text-green-600";
break;
case "death":
case "morte":
Icon = Skull;
chipBg = "bg-zinc-500/10";
chipText = "text-zinc-600";
break;
case "holy":
case "sagrado":
Icon = Cross;
chipBg = "bg-amber-500/10";
chipText = "text-amber-700";
break;
case "physical":
case "fisico":
Icon = Shield;
chipBg = "bg-slate-500/10";
chipText = "text-slate-600";
break;
default:
Icon = Shield;
chipBg = "bg-amber-500/10";
chipText = "text-amber-700";
}
const prettyType =
type.charAt(0).toUpperCase() + type.slice(1);
const label = `${prettyType.replace("fisico", "Físico")}${value ? ` ${value}` : ""}`;
return (
<div
key={`${type}-${idx}`}
className={`flex items-center gap-1 text-xs ${chipBg} ${chipText} px-2 py-1 rounded`}
>
<Icon className="h-3 w-3" />
<span className="whitespace-nowrap">{label}</span>
</div>
);
})}
</ScrollRow>
);
})()}
{item.stats.weight && (
<div className="flex items-center gap-1.5 text-sm text-muted-foreground">
@@ -552,7 +568,7 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
</div>
)}
{(item as any).dropa_de && (
{(item as any).dropa_de &&
(() => {
const raw = String((item as any).dropa_de || "");
const normalized = raw.trim();
@@ -588,8 +604,7 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
</ScrollRow>
</div>
);
})()
)}
})()}
{mode === "market" && item.price && (
<>
@@ -649,7 +664,9 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
<span className="text-sm font-medium text-muted-foreground">
{t("priceHistory")}
</span>
<div className={`flex items-center gap-1 text-xs ${trendColor}`}>
<div
className={`flex items-center gap-1 text-xs ${trendColor}`}
>
<TrendIcon className="h-3 w-3" />
<span className="capitalize">{trend}</span>
</div>
@@ -661,21 +678,27 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
<TrendingUp className="h-3 w-3" />
<span className="font-medium">{t("highest")}</span>
</div>
<div className="font-bold">{formatNumber(item.priceHistory.highest, locale)} gp</div>
<div className="font-bold">
{formatNumber(item.priceHistory.highest, locale)} gp
</div>
</div>
<div className="text-center space-y-1">
<div className="flex items-center justify-center gap-1 text-red-600">
<TrendingDown className="h-3 w-3" />
<span className="font-medium">{t("lowest")}</span>
</div>
<div className="font-bold">{formatNumber(item.priceHistory.lowest, locale)} gp</div>
<div className="font-bold">
{formatNumber(item.priceHistory.lowest, locale)} gp
</div>
</div>
<div className="text-center space-y-1">
<div className="flex items-center justify-center gap-1 text-muted-foreground">
<Minus className="h-3 w-3" />
<span className="font-medium">{t("average")}</span>
</div>
<div className="font-bold">{formatNumber(item.priceHistory.average, locale)} gp</div>
<div className="font-bold">
{formatNumber(item.priceHistory.average, locale)} gp
</div>
</div>
</div>
</div>
@@ -690,7 +713,10 @@ export function ItemCard({ item, mode = "market" }: ItemCardProps) {
>
{t("viewDetails")}
</Button>
<Button className="w-full bg-green-600 hover:bg-green-700 text-white" size="sm">
<Button
className="w-full bg-green-600 hover:bg-green-700 text-white"
size="sm"
>
{t("buyNow")}
</Button>
</div>