import { useEffect, useState } from "react"; import Image from "next/image"; import { games } from "../data/games"; import { usePrivy, useSolanaWallets } from "@privy-io/react-auth"; import { joinBet } from "@/shared/solana_helpers"; import { Bet } from "../types/Bet"; import { fetchUserById } from "@/shared/data_fetcher"; import { toast } from "sonner"; import { connection, EXPLORER_TX_TEMPLATE, API_BASE_URL } from "@/data/shared"; import { CONFIRMATION_THRESHOLD, WAGER_PRIZE_MULT } from "@/shared/constants"; interface GameModalProps { bets: Bet[]; } export default function YourGames({ bets }: GameModalProps) { const { wallets } = useSolanaWallets(); const [myBets, setMyBets] = useState([]); const [loading, setLoading] = useState(true); const { user } = usePrivy(); const [selectedBet, setSelectedBet] = useState(null); // Track selected bet const [isProcessing, setIsProcessing] = useState(false); // Track processing state const [failedImages, setFailedImages] = useState>(new Set()); const defaultPFP = '/duelfiassets/PFP (1).png'; const handleJoinGame = async () => { if (!selectedBet) return; let wallet = wallets[0]; wallets.forEach((_wallet) => { if (wallet.type === "solana") { wallet = _wallet; } }); setIsProcessing(true); toast.loading("Joining Bet"); try { const tx = await joinBet(wallet, user?.id ?? "", selectedBet.id, selectedBet.address); const url = EXPLORER_TX_TEMPLATE.replace("{address}", tx); if (tx.length > 5) { connection.confirmTransaction(tx, CONFIRMATION_THRESHOLD).finally(()=>{ toast.dismiss(); toast.success("Joined game successfully!", { action: { label: "View TX", onClick: () => window.open(url, "_blank"), }, }); }) } else { toast.dismiss(); toast.error("Failed to join this game"); } } catch (error) { console.error("Error joining bet:", error); toast.error("Failed to join this game"); } finally { setIsProcessing(false); setSelectedBet(null); } }; const updateBets = async () => { let filteredBets = bets; if(user){ let wallet = wallets[0]; wallets.forEach((_wallet) => { if (wallet.type === "solana") { wallet = _wallet; } }); filteredBets = bets.filter((bet) => bet.owner !== wallet.address); }else{ console.log("No user found, showing all bets"); } const enrichedBets = await Promise.all( filteredBets.map(async (bet) => { const ownerProfile = await fetchUserById(bet.owner_id); return { ...bet, ownerProfile, }; }) ); setMyBets(enrichedBets); setLoading(false); console.log(`Got ${bets.length} bets, enriched to ${enrichedBets.length}`); }; useEffect(() => { updateBets(); const interval = setInterval(updateBets, 10000); return () => clearInterval(interval); }, [bets]); return (

Open Games

{loading ? (

Loading Open games...

) : myBets.length === 0 ? (

No open games available

) : (
{myBets.map((bet) => { console.log(`Bet ${bet}`); const game = games.find((g) => g.id === bet.id); let ownerPFP = bet.ownerProfile?.x_profile_url || `${API_BASE_URL}profile_pics/${bet.ownerProfile?.id}.jpg`; if (!game) return null; // Check if this image has already failed to load if (failedImages.has(ownerPFP)) { ownerPFP = defaultPFP; } return (
setSelectedBet(bet)} // Open modal >
{game.name}
Join

{game.name}

Wager

Prize

{bet.wager} SOL

{(bet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL

{bet.ownerProfile && (
{bet.ownerProfile.username} { //@ts-expect-error e.target has no src, but it needs to be changed e.target.src = defaultPFP; setFailedImages(prev => new Set(prev).add(ownerPFP)); }} />

{bet.ownerProfile.username}

)}
); })}
)} {/* Modal */} {selectedBet && (
{isProcessing ? (

Processing...

Joining the Game, please wait...

) : ( <>

Are you sure to join this Game?

g.id === selectedBet.id)?.thumbnail || ''} alt={games.find(g => g.id === selectedBet.id)?.name || ''} layout="fill" objectFit="cover" />
{selectedBet.ownerProfile && ( <>

Offered by:

{(() => { let modalOwnerPFP = selectedBet.ownerProfile.x_profile_url || `${API_BASE_URL}profile_pics/${selectedBet.ownerProfile.id}.jpg`; if (failedImages.has(modalOwnerPFP)) { modalOwnerPFP = defaultPFP; } return ( {selectedBet.ownerProfile.username} { //@ts-expect-error e.target has no src, but it needs to be changed e.target.src = defaultPFP; setFailedImages(prev => new Set(prev).add(modalOwnerPFP)); }} /> ); })()}

{selectedBet.ownerProfile.username}

)}
Entry: {selectedBet.wager} SOL
Prize: {(selectedBet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL
)}
)}
); }