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:
1 parent
f35fee944d
commit
7f42def478
55 files changed
+4906
-95
No files matched your search
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user