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

+181 -71
View File
@@ -1,34 +1,32 @@
"use client";
import { useState, useEffect } from "react";
import { useQueryClient } from "@tanstack/react-query";
import {
AlertCircle,
CheckCircle2,
Clock,
Eye,
Heart,
MapPin,
Pause,
ShoppingBag,
Star,
Trash2,
TrendingUp,
X,
} from "lucide-react";
import Image from "next/image";
import { useEffect, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogDescription,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
Eye,
Heart,
Clock,
MapPin,
DollarSign,
Coins,
TrendingUp,
Star,
Pause,
Trash2,
X,
CheckCircle2,
AlertCircle,
ShoppingBag,
} from "lucide-react";
import Image from "next/image";
import { useSession } from "@/lib/hooks/use-session";
import { useQueryClient } from "@tanstack/react-query";
interface Listing {
listing_id: number;
@@ -76,10 +74,11 @@ interface ListingDetailsModalProps {
function formatTimeAgo(date: Date | string): string {
const dateObj = typeof date === "string" ? new Date(date) : date;
const seconds = Math.floor((new Date().getTime() - dateObj.getTime()) / 1000);
const seconds = Math.floor((Date.now() - dateObj.getTime()) / 1000);
if (seconds < 60) return "há alguns segundos";
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return `há ${minutes} ${minutes === 1 ? "minuto" : "minutos"}`;
if (minutes < 60)
return `há ${minutes} ${minutes === 1 ? "minuto" : "minutos"}`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `há ${hours} ${hours === 1 ? "hora" : "horas"}`;
const days = Math.floor(hours / 24);
@@ -92,14 +91,40 @@ function formatTimeAgo(date: Date | string): string {
function getStatusBadge(status: string) {
const statusConfig = {
active: { label: "Ativo", variant: "default" as const, icon: CheckCircle2, className: "bg-green-500 hover:bg-green-600" },
sold: { label: "Vendido", variant: "secondary" as const, icon: CheckCircle2, className: "bg-blue-500 hover:bg-blue-600 text-white" },
cancelled: { label: "Cancelado", variant: "destructive" as const, icon: X, className: "bg-red-500 hover:bg-red-600 text-white" },
in_escrow: { label: "Em Escrow", variant: "default" as const, icon: AlertCircle, className: "bg-yellow-500 hover:bg-yellow-600 text-white" },
expired: { label: "Expirado", variant: "secondary" as const, icon: Clock, className: "bg-gray-500 hover:bg-gray-600 text-white" },
active: {
label: "Ativo",
variant: "default" as const,
icon: CheckCircle2,
className: "bg-green-500 hover:bg-green-600",
},
sold: {
label: "Vendido",
variant: "secondary" as const,
icon: CheckCircle2,
className: "bg-blue-500 hover:bg-blue-600 text-white",
},
cancelled: {
label: "Cancelado",
variant: "destructive" as const,
icon: X,
className: "bg-red-500 hover:bg-red-600 text-white",
},
in_escrow: {
label: "Em Escrow",
variant: "default" as const,
icon: AlertCircle,
className: "bg-yellow-500 hover:bg-yellow-600 text-white",
},
expired: {
label: "Expirado",
variant: "secondary" as const,
icon: Clock,
className: "bg-gray-500 hover:bg-gray-600 text-white",
},
};
const config = statusConfig[status as keyof typeof statusConfig] || statusConfig.active;
const config =
statusConfig[status as keyof typeof statusConfig] || statusConfig.active;
const Icon = config.icon;
return (
@@ -123,7 +148,7 @@ export function ListingDetailsModal({
const [itemImageUrl, setItemImageUrl] = useState<string>("");
const [showMarkSoldDialog, setShowMarkSoldDialog] = useState(false);
const [markingSold, setMarkingSold] = useState(false);
// Verificar se o usuário é o dono do anúncio
const isOwner = user && user.userId === listing.seller_id;
@@ -134,13 +159,19 @@ export function ListingDetailsModal({
} else if (listing.image_local_path) {
const normalizedPath = listing.image_local_path.replace(/\\/g, "/");
if (normalizedPath.startsWith("data/")) {
setItemImageUrl(`/api/images?path=${encodeURIComponent(normalizedPath)}`);
setItemImageUrl(
`/api/images?path=${encodeURIComponent(normalizedPath)}`,
);
} else {
const category = listing.item_category || "other";
setItemImageUrl(`/api/images?path=${encodeURIComponent(`data/images/${category}/${normalizedPath}`)}`);
setItemImageUrl(
`/api/images?path=${encodeURIComponent(`data/images/${category}/${normalizedPath}`)}`,
);
}
} else if (listing.item_id_unified) {
const params = new URLSearchParams({ item: listing.item_id_unified.toString() });
const params = new URLSearchParams({
item: listing.item_id_unified.toString(),
});
if (listing.item_name) {
params.set("name", listing.item_name);
}
@@ -158,27 +189,52 @@ export function ListingDetailsModal({
const prices: Array<{ type: string; label: string; value: string }> = [];
if (listing.price_pix) {
const price = typeof listing.price_pix === "string" ? parseFloat(listing.price_pix) : listing.price_pix;
if (!isNaN(price)) {
prices.push({ type: "pix", label: "PIX", value: `R$ ${price.toFixed(2)}` });
const price =
typeof listing.price_pix === "string"
? parseFloat(listing.price_pix)
: listing.price_pix;
if (!Number.isNaN(price)) {
prices.push({
type: "pix",
label: "PIX",
value: `R$ ${price.toFixed(2)}`,
});
}
}
if (listing.price_tibia_coins) {
const price = typeof listing.price_tibia_coins === "string" ? parseInt(listing.price_tibia_coins, 10) : listing.price_tibia_coins;
if (!isNaN(price)) {
prices.push({ type: "tibia_coins", label: "Tibia Coins", value: `${price.toLocaleString()} TC` });
const price =
typeof listing.price_tibia_coins === "string"
? parseInt(listing.price_tibia_coins, 10)
: listing.price_tibia_coins;
if (!Number.isNaN(price)) {
prices.push({
type: "tibia_coins",
label: "Tibia Coins",
value: `${price.toLocaleString()} TC`,
});
}
}
if (listing.price_gold_coins) {
const price = typeof listing.price_gold_coins === "string" ? parseInt(listing.price_gold_coins, 10) : listing.price_gold_coins;
if (!isNaN(price)) {
prices.push({ type: "gold_coins", label: "Gold Coins", value: `${price.toLocaleString()} GP` });
const price =
typeof listing.price_gold_coins === "string"
? parseInt(listing.price_gold_coins, 10)
: listing.price_gold_coins;
if (!Number.isNaN(price)) {
prices.push({
type: "gold_coins",
label: "Gold Coins",
value: `${price.toLocaleString()} GP`,
});
}
}
if (listing.trade_item_id && listing.trade_item_name && listing.trade_item_quantity) {
if (
listing.trade_item_id &&
listing.trade_item_name &&
listing.trade_item_quantity
) {
prices.push({
type: "trade",
label: "Troca",
@@ -220,7 +276,10 @@ export function ListingDetailsModal({
const canPause = isOwner && listing.listing_status === "active";
const canActivate = isOwner && listing.listing_status === "cancelled";
const canCancel = isOwner && listing.listing_status === "active";
const canMarkAsSold = isOwner && (listing.listing_status === "active" || listing.listing_status === "in_escrow");
const canMarkAsSold =
isOwner &&
(listing.listing_status === "active" ||
listing.listing_status === "in_escrow");
const handleMarkAsSold = async () => {
setMarkingSold(true);
@@ -228,7 +287,7 @@ export function ListingDetailsModal({
const res = await fetch(`/api/listings/${listing.listing_id}/mark-sold`, {
method: "POST",
});
if (!res.ok) {
const data = await res.json();
throw new Error(data.error || "Erro ao marcar como vendido");
@@ -237,12 +296,14 @@ export function ListingDetailsModal({
// Invalidar cache para atualizar a lista
queryClient.invalidateQueries({ queryKey: ["listings"] });
queryClient.invalidateQueries({ queryKey: ["my-listings"] });
setShowMarkSoldDialog(false);
onOpenChange(false);
} catch (error) {
console.error("Erro ao marcar como vendido:", error);
alert(error instanceof Error ? error.message : "Erro ao marcar como vendido");
alert(
error instanceof Error ? error.message : "Erro ao marcar como vendido",
);
} finally {
setMarkingSold(false);
}
@@ -256,7 +317,9 @@ export function ListingDetailsModal({
Detalhes do Anúncio
{getStatusBadge(listing.listing_status)}
</DialogTitle>
<DialogDescription>Informações completas do seu anúncio</DialogDescription>
<DialogDescription>
Informações completas do seu anúncio
</DialogDescription>
</DialogHeader>
<div className="space-y-6">
@@ -294,22 +357,30 @@ export function ListingDetailsModal({
<div className="flex items-center gap-2">
<Eye className="h-4 w-4 text-muted-foreground" />
<div>
<div className="text-sm text-muted-foreground">Visualizações</div>
<div className="text-sm text-muted-foreground">
Visualizações
</div>
<div className="font-semibold">{listing.views_count}</div>
</div>
</div>
<div className="flex items-center gap-2">
<Heart className="h-4 w-4 text-muted-foreground" />
<div>
<div className="text-sm text-muted-foreground">Favoritos</div>
<div className="font-semibold">{listing.favorites_count || 0}</div>
<div className="text-sm text-muted-foreground">
Favoritos
</div>
<div className="font-semibold">
{listing.favorites_count || 0}
</div>
</div>
</div>
<div className="flex items-center gap-2">
<Clock className="h-4 w-4 text-muted-foreground" />
<div>
<div className="text-sm text-muted-foreground">Criado</div>
<div className="font-semibold text-xs">{formatTimeAgo(listing.created_at)}</div>
<div className="font-semibold text-xs">
{formatTimeAgo(listing.created_at)}
</div>
</div>
</div>
</div>
@@ -349,7 +420,9 @@ export function ListingDetailsModal({
: "bg-purple-500/10 border-purple-500/20"
}`}
>
<div className="text-xs text-muted-foreground mb-1">{price.label}</div>
<div className="text-xs text-muted-foreground mb-1">
{price.label}
</div>
<div className="font-semibold">{price.value}</div>
</div>
))}
@@ -370,26 +443,44 @@ export function ListingDetailsModal({
<div className="flex justify-between">
<span className="text-muted-foreground">Lance Atual:</span>
<span className="font-semibold text-lg text-primary">
R$ {typeof listing.current_bid_amount === "number" ? listing.current_bid_amount.toFixed(2) : parseFloat(String(listing.current_bid_amount)).toFixed(2)}
R${" "}
{typeof listing.current_bid_amount === "number"
? listing.current_bid_amount.toFixed(2)
: parseFloat(
String(listing.current_bid_amount),
).toFixed(2)}
</span>
</div>
{listing.min_bid_increment && (
<div className="flex justify-between">
<span className="text-muted-foreground">Incremento Mínimo:</span>
<span className="text-muted-foreground">
Incremento Mínimo:
</span>
<span className="font-medium">
R$ {typeof listing.min_bid_increment === "number" ? listing.min_bid_increment.toFixed(2) : parseFloat(String(listing.min_bid_increment)).toFixed(2)}
R${" "}
{typeof listing.min_bid_increment === "number"
? listing.min_bid_increment.toFixed(2)
: parseFloat(
String(listing.min_bid_increment),
).toFixed(2)}
</span>
</div>
)}
{listing.auction_ends_at && (
<div className="flex justify-between">
<span className="text-muted-foreground">Termina em:</span>
<span className="font-medium">{new Date(listing.auction_ends_at).toLocaleString("pt-BR")}</span>
<span className="font-medium">
{new Date(listing.auction_ends_at).toLocaleString(
"pt-BR",
)}
</span>
</div>
)}
</div>
) : (
<div className="text-center text-muted-foreground py-2">Sem lances ainda</div>
<div className="text-center text-muted-foreground py-2">
Sem lances ainda
</div>
)}
</div>
)}
@@ -398,7 +489,9 @@ export function ListingDetailsModal({
{listing.description && (
<div className="space-y-2">
<h4 className="font-semibold">Descrição</h4>
<p className="text-sm text-muted-foreground p-3 bg-muted rounded-lg">{listing.description}</p>
<p className="text-sm text-muted-foreground p-3 bg-muted rounded-lg">
{listing.description}
</p>
</div>
)}
@@ -410,13 +503,19 @@ export function ListingDetailsModal({
</div>
{listing.item_id_unified && (
<div>
<span className="text-muted-foreground">ID do Item (Unificado):</span>
<span className="ml-2 font-mono">{listing.item_id_unified}</span>
<span className="text-muted-foreground">
ID do Item (Unificado):
</span>
<span className="ml-2 font-mono">
{listing.item_id_unified}
</span>
</div>
)}
<div>
<span className="text-muted-foreground">Criado em:</span>
<span className="ml-2">{new Date(listing.created_at).toLocaleString("pt-BR")}</span>
<span className="ml-2">
{new Date(listing.created_at).toLocaleString("pt-BR")}
</span>
</div>
</div>
@@ -424,9 +523,9 @@ export function ListingDetailsModal({
{(canPause || canActivate || canCancel || canMarkAsSold) && (
<div className="flex gap-2 pt-4 border-t">
{canMarkAsSold && (
<Button
variant="default"
onClick={() => setShowMarkSoldDialog(true)}
<Button
variant="default"
onClick={() => setShowMarkSoldDialog(true)}
className="flex-1 bg-green-600 hover:bg-green-700"
>
<ShoppingBag className="h-4 w-4 mr-2" />
@@ -440,13 +539,21 @@ export function ListingDetailsModal({
</Button>
)}
{canActivate && onActivate && (
<Button variant="default" onClick={onActivate} className="flex-1">
<Button
variant="default"
onClick={onActivate}
className="flex-1"
>
<CheckCircle2 className="h-4 w-4 mr-2" />
Reativar Anúncio
</Button>
)}
{canCancel && (
<Button variant="destructive" onClick={onCancel} className="flex-1">
<Button
variant="destructive"
onClick={onCancel}
className="flex-1"
>
<Trash2 className="h-4 w-4 mr-2" />
Cancelar Anúncio
</Button>
@@ -462,14 +569,18 @@ export function ListingDetailsModal({
<DialogHeader>
<DialogTitle>Marcar anúncio como vendido?</DialogTitle>
<DialogDescription>
Ao marcar este anúncio como vendido, as seguintes ações serão executadas:
Ao marcar este anúncio como vendido, as seguintes ações serão
executadas:
</DialogDescription>
</DialogHeader>
<div className="space-y-2 pt-2">
<ul className="list-disc list-inside space-y-1 text-sm text-muted-foreground">
<li>O anúncio será marcado como "Vendido"</li>
<li>O anúncio continuará visível na lista por mais 1 hora</li>
<li>Após 1 hora, o anúncio sairá automaticamente da lista de anúncios ativos</li>
<li>
Após 1 hora, o anúncio sairá automaticamente da lista de
anúncios ativos
</li>
<li>Nenhuma interação (comprar, dar lance) será permitida</li>
</ul>
<p className="pt-2 font-medium text-foreground">
@@ -497,4 +608,3 @@ export function ListingDetailsModal({
</Dialog>
);
}