2023-07-24 11:17:07 -07:00
|
|
|
|
// import { useTranslation } from 'next-i18next'
|
|
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
|
import {
|
|
|
|
|
useAuctionHouse,
|
|
|
|
|
useBids,
|
|
|
|
|
useListings,
|
|
|
|
|
useLoadBids,
|
|
|
|
|
} from 'hooks/market/useAuctionHouse'
|
|
|
|
|
import { toUiDecimals } from '@blockworks-foundation/mango-v4'
|
|
|
|
|
import { MANGO_MINT_DECIMALS } from 'utils/governance/constants'
|
|
|
|
|
import { useWallet } from '@solana/wallet-adapter-react'
|
|
|
|
|
import metaplexStore from '@store/metaplexStore'
|
|
|
|
|
import { Bid, Listing, PublicBid, PublicKey } from '@metaplex-foundation/js'
|
|
|
|
|
import BidNftModal from './BidNftModal'
|
|
|
|
|
import mangoStore from '@store/mangoStore'
|
|
|
|
|
import {
|
|
|
|
|
Table,
|
|
|
|
|
TableDateDisplay,
|
|
|
|
|
Td,
|
|
|
|
|
Th,
|
|
|
|
|
TrBody,
|
|
|
|
|
TrHead,
|
|
|
|
|
} from '@components/shared/TableElements'
|
|
|
|
|
import { ImgWithLoader } from '@components/ImgWithLoader'
|
|
|
|
|
import NftMarketButton from './NftMarketButton'
|
|
|
|
|
import { abbreviateAddress } from 'utils/formatting'
|
2023-08-18 05:59:30 -07:00
|
|
|
|
import EmptyState from './EmptyState'
|
|
|
|
|
import { formatNumericValue } from 'utils/numbers'
|
2023-08-23 19:35:02 -07:00
|
|
|
|
import Loading from '@components/shared/Loading'
|
2023-07-24 11:17:07 -07:00
|
|
|
|
|
|
|
|
|
const AllBidsView = () => {
|
|
|
|
|
const { publicKey } = useWallet()
|
|
|
|
|
const { data: auctionHouse } = useAuctionHouse()
|
|
|
|
|
const metaplex = metaplexStore((s) => s.metaplex)
|
|
|
|
|
// const { t } = useTranslation(['nft-market'])
|
|
|
|
|
const [showBidModal, setShowBidModal] = useState(false)
|
|
|
|
|
const [bidListing, setBidListing] = useState<null | Listing>(null)
|
2023-08-23 19:35:02 -07:00
|
|
|
|
const [buying, setBuying] = useState('')
|
|
|
|
|
const [cancellingBid, setCancellingBid] = useState('')
|
2023-07-24 11:17:07 -07:00
|
|
|
|
const { data: bids, refetch } = useBids()
|
|
|
|
|
const bidsToLoad = bids ? bids : []
|
|
|
|
|
const { data: loadedBids } = useLoadBids(bidsToLoad)
|
|
|
|
|
const connection = mangoStore((s) => s.connection)
|
|
|
|
|
const fetchNfts = mangoStore((s) => s.actions.fetchNfts)
|
|
|
|
|
const nfts = mangoStore((s) => s.wallet.nfts.data)
|
|
|
|
|
const { data: listings } = useListings()
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (publicKey) {
|
|
|
|
|
fetchNfts(connection, publicKey!)
|
|
|
|
|
}
|
|
|
|
|
}, [publicKey])
|
|
|
|
|
|
|
|
|
|
const cancelBid = async (bid: Bid) => {
|
2023-08-23 19:35:02 -07:00
|
|
|
|
setCancellingBid(bid.asset.mint.address.toString())
|
|
|
|
|
try {
|
|
|
|
|
await metaplex!.auctionHouse().cancelBid({
|
|
|
|
|
auctionHouse: auctionHouse!,
|
|
|
|
|
bid,
|
|
|
|
|
})
|
|
|
|
|
refetch()
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log('error cancelling bid', e)
|
|
|
|
|
} finally {
|
|
|
|
|
setCancellingBid('')
|
|
|
|
|
}
|
2023-07-24 11:17:07 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sellAsset = async (bid: Bid, tokenAccountPk: string) => {
|
|
|
|
|
const tokenAccount = await metaplex
|
|
|
|
|
?.tokens()
|
|
|
|
|
.findTokenByAddress({ address: new PublicKey(tokenAccountPk) })
|
|
|
|
|
|
|
|
|
|
await metaplex!.auctionHouse().sell({
|
|
|
|
|
auctionHouse: auctionHouse!,
|
|
|
|
|
bid: bid as PublicBid,
|
|
|
|
|
sellerToken: tokenAccount!,
|
|
|
|
|
})
|
|
|
|
|
refetch()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const buyAsset = async (listing: Listing) => {
|
2023-08-23 19:35:02 -07:00
|
|
|
|
setBuying(listing.asset.mint.address.toString())
|
|
|
|
|
try {
|
|
|
|
|
await metaplex!.auctionHouse().buy({
|
|
|
|
|
auctionHouse: auctionHouse!,
|
|
|
|
|
listing,
|
|
|
|
|
})
|
|
|
|
|
refetch()
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log('error buying nft', e)
|
|
|
|
|
} finally {
|
|
|
|
|
setBuying('')
|
|
|
|
|
}
|
2023-07-24 11:17:07 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const openBidModal = (listing: Listing) => {
|
|
|
|
|
setBidListing(listing)
|
|
|
|
|
setShowBidModal(true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<div className="flex flex-col">
|
|
|
|
|
{loadedBids?.length ? (
|
|
|
|
|
<Table>
|
|
|
|
|
<thead>
|
|
|
|
|
<TrHead>
|
|
|
|
|
<Th className="text-left">Date</Th>
|
|
|
|
|
<Th className="text-right">NFT</Th>
|
|
|
|
|
<Th className="text-right">Offer</Th>
|
|
|
|
|
<Th className="text-right">Buy Now Price</Th>
|
|
|
|
|
<Th className="text-right">Buyer</Th>
|
|
|
|
|
<Th className="text-right">Actions</Th>
|
|
|
|
|
</TrHead>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
{loadedBids
|
|
|
|
|
.sort((a, b) => b.createdAt.toNumber() - a.createdAt.toNumber())
|
|
|
|
|
.map((x, idx) => {
|
|
|
|
|
const listing = listings?.results?.find(
|
|
|
|
|
(nft: Listing) =>
|
2023-07-24 15:52:09 -07:00
|
|
|
|
nft.asset.mint.toString() === x.asset.mint.toString(),
|
2023-07-24 11:17:07 -07:00
|
|
|
|
)
|
|
|
|
|
return (
|
|
|
|
|
<TrBody key={idx}>
|
|
|
|
|
<Td>
|
|
|
|
|
<TableDateDisplay
|
2023-08-23 22:31:54 -07:00
|
|
|
|
date={x.createdAt.toNumber() * 1000}
|
2023-07-24 11:17:07 -07:00
|
|
|
|
showSeconds
|
|
|
|
|
/>
|
|
|
|
|
</Td>
|
|
|
|
|
<Td>
|
|
|
|
|
<div className="flex justify-end">
|
|
|
|
|
<ImgWithLoader
|
|
|
|
|
className="w-12 rounded-md"
|
|
|
|
|
alt={x.asset.name}
|
|
|
|
|
src={x.asset.json!.image!}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</Td>
|
|
|
|
|
<Td>
|
|
|
|
|
<p className="text-right">
|
2023-08-18 05:59:30 -07:00
|
|
|
|
{formatNumericValue(
|
|
|
|
|
toUiDecimals(
|
|
|
|
|
x.price.basisPoints.toNumber(),
|
|
|
|
|
MANGO_MINT_DECIMALS,
|
|
|
|
|
),
|
2023-07-24 11:17:07 -07:00
|
|
|
|
)}
|
|
|
|
|
<span className="font-body">{' MNGO'}</span>
|
|
|
|
|
</p>
|
|
|
|
|
</Td>
|
|
|
|
|
<Td>
|
|
|
|
|
<p className="text-right">
|
|
|
|
|
<p className="text-right">
|
|
|
|
|
{listing ? (
|
|
|
|
|
<>
|
2023-08-18 05:59:30 -07:00
|
|
|
|
{formatNumericValue(
|
|
|
|
|
toUiDecimals(
|
|
|
|
|
listing.price.basisPoints.toNumber(),
|
|
|
|
|
MANGO_MINT_DECIMALS,
|
|
|
|
|
),
|
2023-07-24 11:17:07 -07:00
|
|
|
|
)}
|
|
|
|
|
<span className="font-body">{' MNGO'}</span>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
'–'
|
|
|
|
|
)}
|
|
|
|
|
</p>
|
|
|
|
|
</p>
|
|
|
|
|
</Td>
|
|
|
|
|
<Td>
|
|
|
|
|
<p className="text-right">
|
|
|
|
|
{abbreviateAddress(x.buyerAddress)}
|
|
|
|
|
</p>
|
|
|
|
|
</Td>
|
|
|
|
|
<Td>
|
|
|
|
|
<div className="flex justify-end space-x-2">
|
|
|
|
|
{publicKey &&
|
|
|
|
|
!x.buyerAddress.equals(publicKey) &&
|
|
|
|
|
nfts.find(
|
|
|
|
|
(ownNft) =>
|
2023-07-24 15:52:09 -07:00
|
|
|
|
ownNft.mint === x.asset.address.toBase58(),
|
2023-07-24 11:17:07 -07:00
|
|
|
|
) ? (
|
|
|
|
|
<NftMarketButton
|
|
|
|
|
onClick={() =>
|
|
|
|
|
sellAsset(
|
|
|
|
|
x,
|
|
|
|
|
nfts.find(
|
|
|
|
|
(ownNft) =>
|
2023-07-24 15:52:09 -07:00
|
|
|
|
ownNft.mint ===
|
|
|
|
|
x.asset.address.toBase58(),
|
|
|
|
|
)!.tokenAccount,
|
2023-07-24 11:17:07 -07:00
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
colorClass="fgd-3"
|
|
|
|
|
text="Accept Offer"
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
{publicKey && x.buyerAddress.equals(publicKey) ? (
|
|
|
|
|
<NftMarketButton
|
|
|
|
|
colorClass="error"
|
2023-08-23 19:35:02 -07:00
|
|
|
|
text={
|
|
|
|
|
cancellingBid ===
|
|
|
|
|
x.asset.mint.address.toString() ? (
|
|
|
|
|
<Loading />
|
|
|
|
|
) : (
|
|
|
|
|
'Cancel Offer'
|
|
|
|
|
)
|
|
|
|
|
}
|
2023-07-24 11:17:07 -07:00
|
|
|
|
onClick={() => cancelBid(x)}
|
|
|
|
|
/>
|
|
|
|
|
) : listing ? (
|
|
|
|
|
<NftMarketButton
|
|
|
|
|
colorClass="fgd-3"
|
|
|
|
|
text="Make Offer"
|
|
|
|
|
onClick={() => openBidModal(listing)}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
{listing ? (
|
|
|
|
|
<NftMarketButton
|
|
|
|
|
colorClass="success"
|
2023-08-23 19:35:02 -07:00
|
|
|
|
text={
|
|
|
|
|
buying ===
|
|
|
|
|
listing.asset.mint.address.toString() ? (
|
|
|
|
|
<Loading />
|
|
|
|
|
) : (
|
|
|
|
|
'Buy Now'
|
|
|
|
|
)
|
|
|
|
|
}
|
2023-07-24 11:17:07 -07:00
|
|
|
|
onClick={() => buyAsset(listing)}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</Td>
|
|
|
|
|
</TrBody>
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</tbody>
|
|
|
|
|
</Table>
|
|
|
|
|
) : (
|
2023-08-18 05:59:30 -07:00
|
|
|
|
<EmptyState text="No offers to display..." />
|
2023-07-24 11:17:07 -07:00
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
{showBidModal ? (
|
|
|
|
|
<BidNftModal
|
|
|
|
|
listing={bidListing ? bidListing : undefined}
|
|
|
|
|
isOpen={showBidModal}
|
|
|
|
|
onClose={() => setShowBidModal(false)}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
</>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default AllBidsView
|