feat(market): add Minha Intenções tab with panel, hook, and badge

- Introduced "Minhas Intenções" tab visible only to logged-in users.
- Integrated MyPurchaseIntentionsPanel and useMyPurchaseIntentions hook.
- Added tab badge showing count of pending intentions.
- Extended session API to include user’s main character for downstream features.
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-07 17:25:51 -03:00
1 parent f35fee944d
commit 7f42def478
55 files changed
+4906 -95

No files matched your search

+55 -5
View File
@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Heart, Clock, Eye, Star, MapPin, DollarSign, Coins, RefreshCw, ShoppingCart, TrendingUp, User } from "lucide-react";
import { Heart, Clock, Eye, Star, MapPin, DollarSign, Coins, RefreshCw, ShoppingCart, TrendingUp, User, MessageCircle } from "lucide-react";
import { useAdTracking, useMarketTelemetry } from "@/lib/hooks/use-telemetry";
import { useSession } from "@/lib/hooks/use-session";
import { useQueryClient } from "@tanstack/react-query";
@@ -15,6 +15,7 @@ import { BidModal } from "./BidModal";
import { SellerInfo } from "./SellerInfo";
import { ListingDetailsModal } from "./ListingDetailsModal";
import { AuctionCountdown } from "./AuctionCountdown";
import { ChatModal } from "@/components/chat/ChatModal";
// Função auxiliar para formatar tempo relativo
function formatTimeAgo(date: Date): string {
@@ -66,6 +67,7 @@ interface Listing {
item_category?: string | null;
// Campo do vendedor
seller_character_name?: string | null;
has_pending_intention_for_current_user?: boolean;
}
interface PriceInfo {
@@ -88,6 +90,7 @@ export function AdCard({ listing, viewMode = "grid" }: AdCardProps) {
const [showPurchaseModal, setShowPurchaseModal] = useState(false);
const [showBidModal, setShowBidModal] = useState(false);
const [showDetailsModal, setShowDetailsModal] = useState(false);
const [showChatModal, setShowChatModal] = useState(false);
const invalidateCache = () => {
queryClient.invalidateQueries({ queryKey: ["listings"] });
@@ -261,6 +264,7 @@ export function AdCard({ listing, viewMode = "grid" }: AdCardProps) {
const timeAgo = formatTimeAgo(new Date(listing.created_at));
const availablePrices = getAvailablePrices();
const isSold = listing.listing_status === "sold";
const hasPendingIntention = Boolean(listing.has_pending_intention_for_current_user);
// Função para obter URL da imagem do item
const getItemImageUrl = (): string => {
@@ -662,6 +666,20 @@ export function AdCard({ listing, viewMode = "grid" }: AdCardProps) {
Comprar
</Button>
)}
{user && user.userId !== listing.seller_id && !isSold && (
<Button
variant="outline"
size="sm"
className="transition-all duration-200 hover:scale-105"
onClick={(e) => {
e.stopPropagation();
setShowChatModal(true);
}}
>
<MessageCircle className="h-4 w-4 mr-2" />
Chat
</Button>
)}
</div>
)}
{isSold && (
@@ -932,15 +950,40 @@ export function AdCard({ listing, viewMode = "grid" }: AdCardProps) {
<Button
variant="default"
size="sm"
className={cn(
"flex-1 transition-all duration-200 hover:scale-105",
(isSold || hasPendingIntention) && "opacity-60 cursor-not-allowed hover:scale-100"
)}
onClick={(e) => {
e.stopPropagation();
if (hasPendingIntention) {
return;
}
setShowPurchaseModal(true);
}}
disabled={isSold || hasPendingIntention}
title={
hasPendingIntention
? "Você já enviou uma intenção para este anúncio. Gerencie em Minhas intenções."
: undefined
}
>
<ShoppingCart className="h-4 w-4 mr-2" />
{hasPendingIntention ? "Intenção pendente" : "Comprar"}
</Button>
)}
{user && user.userId !== listing.seller_id && !isSold && (
<Button
variant="outline"
size="sm"
className="flex-1 transition-all duration-200 hover:scale-105"
onClick={(e) => {
e.stopPropagation();
setShowPurchaseModal(true);
setShowChatModal(true);
}}
disabled={isSold}
>
<ShoppingCart className="h-4 w-4 mr-2" />
Comprar
<MessageCircle className="h-4 w-4 mr-2" />
Chat
</Button>
)}
</>
@@ -1021,6 +1064,13 @@ export function AdCard({ listing, viewMode = "grid" }: AdCardProps) {
onActivate={handleActivate}
onCancel={handleCancel}
/>
{user && user.userId !== listing.seller_id && (
<ChatModal
open={showChatModal}
onOpenChange={setShowChatModal}
listingId={listing.listing_id}
/>
)}
</Card>
);
}