import { useQueryClient } from "@tanstack/react-query"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router"; import { toast } from "react-toastify"; import { formatEther, parseEther, type Address } from "viem"; import { useBalance, useConnection, useReadContract, useReadContracts, useWaitForTransactionReceipt, useWatchContractEvent, useWriteContract } from "wagmi"; import { LoadingView } from "~/components/loading/LoadingView"; import { auctionABI, auctionContractAddress } from "~/config/auction"; function WalletBalanceCard({ address }: { address: Address }) { const { data: balance, error } = useBalance({ address }); if (error) { return

Failed to fetch wallet balance.

; } return (

Wallet Balance

Funds
{balance ? Number(formatEther(balance.value)).toLocaleString() : '...'} ETH
) } function BestOfferCard({ address }: { address: Address }) { const { data: bestOffer, error } = useReadContracts({ contracts: [ { address: auctionContractAddress, abi: auctionABI, functionName: 'highestAmount' }, { address: auctionContractAddress, abi: auctionABI, functionName: 'highestBidder' } ] }); const [amount, bidder] = bestOffer || []; if (error || amount?.error || bidder?.error) { return

Failed to fetch best bid.

; } return (

Best Offer

Top Bid
{amount?.result !== undefined ? Number(formatEther(amount.result)).toLocaleString() : '...'} ETH ({bidder?.result === address ? "by you" : "by someone else"})
) } function LastEventCard({ event }: { event?: string }) { return (

Last Event

Update
{event || 'No events yet...'}
) } function PendingReturnCard({ address }: { address: Address }) { const { data: refundValue, error } = useReadContract({ address: auctionContractAddress, abi: auctionABI, functionName: 'pendingReturnAmount', args: [address] }); if (error) { return

Failed to fetch refund amount.

; } return (

Pending Return

Your Refund
{refundValue !== undefined ? Number(formatEther(refundValue)).toLocaleString() : '...'} ETH
) } function MakeBidCard() { const [inputValue, setInputValue] = useState(""); const isValidInput = inputValue && !isNaN(Number(inputValue)) && Number(inputValue) > 0; const { data: hash, mutate: makeBid, isPending: isWaitingForUser, error: userError, reset } = useWriteContract(); const { data: receipt, isPending, isFetching, error: receiptError } = useWaitForTransactionReceipt({ hash }) function onSubmit(e) { e.preventDefault(); if (!isValidInput) { toast.error('Invalid bid amount.'); return; } makeBid({ address: auctionContractAddress, abi: auctionABI, functionName: 'bid', value: parseEther(inputValue) }) } return (

Make Bid

Bid
auction

Enter your bid amount in ETH

{ setInputValue(e.target.value); if (hash || userError) { reset(); } }} />
{isWaitingForUser &&

Waiting for user...

} {(userError || receiptError) &&

Failed to make bid.

} {(isPending && isFetching) &&

Waiting for receipt...

} {receipt &&

Status: {receipt.status}

}
) } export function WithdrawCard({ address }: { address: Address }) { const { data: refundValue, isPending: isRefundValuePending, error: refundValueError } = useReadContract({ address: auctionContractAddress, abi: auctionABI, functionName: 'pendingReturnAmount', args: [address] }); const queryClient = useQueryClient(); const { data: hash, mutate: withdraw, isPending: isWaitingForUser, error: userError } = useWriteContract(); const { data: receipt, isPending, isFetching, error: receiptError } = useWaitForTransactionReceipt({ hash }); useEffect(() => { if (hash && receipt?.status === 'success') { queryClient.invalidateQueries(); } }, [receipt, hash, queryClient]); function onWithdraw(e) { e.preventDefault(); withdraw({ address: auctionContractAddress, abi: auctionABI, functionName: 'withdraw' }) } if (refundValueError) { return

Failed to fetch refund value.

; } if (isRefundValuePending || !refundValue) { // don't render the component if there is nothing to withdraw return null; } return (

Withdraw

Refund
withdraw

Withdraw your funds

Click the button to withdraw your funds

{isWaitingForUser &&

Waiting for user...

} {(userError || receiptError) &&

Failed to withdraw.

} {(isFetching && isPending) &&

Waiting for receipt...

} {receipt &&

Status: {receipt.status}

}
) } export function AuctionPage() { const { address, isConnected } = useConnection(); const [isReady, setIsReady] = useState(false); const navigate = useNavigate(); useEffect(() => { if (!isConnected) { navigate("/status"); } else if (address && !isReady) { setIsReady(true); } }, [isConnected, address, isReady, navigate, setIsReady]); const [lastEvent, setLastEvent] = useState(); const queryClient = useQueryClient(); useWatchContractEvent({ address: auctionContractAddress, abi: auctionABI, onLogs: (logs) => { if (logs.length > 0) { setLastEvent(logs[logs.length - 1].eventName); queryClient.invalidateQueries(); } } }) if (!isConnected || !address || !isReady) { return ; } return (
) }