import { toUiDecimals } from '@blockworks-foundation/mango-v4' import Select from '@components/forms/Select' import BidNftModal from '@components/nftMarket/BidNftModal' import AssetBidsModal from '@components/nftMarket/AssetBidsModal' import { Listing } from '@metaplex-foundation/js' import { useWallet } from '@solana/wallet-adapter-react' import metaplexStore from '@store/metaplexStore' import { ALL_FILTER, useAuctionHouse, useBids, useLazyListings, useListings, } from 'hooks/market/useAuctionHouse' import { useCallback, useEffect, useMemo, useState } from 'react' import { MANGO_MINT_DECIMALS } from 'utils/governance/constants' // import { useTranslation } from 'next-i18next' import { ImgWithLoader } from '@components/ImgWithLoader' import NftMarketButton from './NftMarketButton' import { formatNumericValue } from 'utils/numbers' import Loading from '@components/shared/Loading' import SheenLoader from '@components/shared/SheenLoader' import EmptyState from './EmptyState' const YOUR_LISTINGS = 'Your Listings' const PRICE_LOW_HIGH = 'Price: Low to High' const PRICE_HIGH_LOW = 'Price: High to Low' const defaultFilters = [ ALL_FILTER, YOUR_LISTINGS, PRICE_LOW_HIGH, PRICE_HIGH_LOW, ] const ListingsView = () => { const { publicKey } = useWallet() const metaplex = metaplexStore((s) => s.metaplex) // const { t } = useTranslation(['nft-market']) const [currentFilter, setCurrentFilter] = useState(ALL_FILTER) const { data: bids } = useBids() const [bidListing, setBidListing] = useState(null) const [assetBidsListing, setAssetBidsListing] = useState(null) const { data: auctionHouse } = useAuctionHouse() const [asssetBidsModal, setAssetBidsModal] = useState(false) const [bidNftModal, setBidNftModal] = useState(false) const [cancellingListing, setCancellingListing] = useState('') const [buying, setBuying] = useState('') const { refetch } = useLazyListings() const { data: listings, isLoading: loadingListings, isFetching: fetchingListings, } = useListings() const [listingsToShow, setListingsToShow] = useState( undefined, ) useEffect(() => { if ( (!listingsToShow || !listingsToShow.length) && listings?.results.length ) { const sortedResults = listings.results.sort( (a, b) => b.createdAt.toNumber() - a.createdAt.toNumber(), ) setListingsToShow(sortedResults) } }, [listings]) const cancelListing = async (listing: Listing) => { setCancellingListing(listing.asset.mint.address.toString()) try { await metaplex!.auctionHouse().cancelListing({ auctionHouse: auctionHouse!, listing: listing, }) refetch() } catch (e) { console.log('error cancelling listing', e) } finally { setCancellingListing('') } } const buyAsset = async (listing: Listing) => { 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('') } } const openBidModal = (listing: Listing) => { setBidListing(listing) setBidNftModal(true) } const closeBidModal = () => { setBidNftModal(false) setBidListing(null) } const openBidsModal = (listing: Listing) => { setAssetBidsModal(true) setAssetBidsListing(listing) } const closeBidsModal = () => { setAssetBidsModal(false) setAssetBidsListing(null) } // const handlePageClick = (page: number) => { // setPage(page) // } const filters = useMemo(() => { if (!listings?.results || !listings?.results.length) return defaultFilters const collections: string[] = [] for (const listing of listings.results) { const collectionName = listing.asset.json?.collection?.family || 'Unknown' if (!collections.includes(collectionName)) { collections.push(collectionName) } } return defaultFilters.concat(collections.sort((a, b) => a.localeCompare(b))) }, [listings]) const handleFilter = useCallback( (filter: string) => { setCurrentFilter(filter) if (filter === ALL_FILTER) { const sortedResults = listings?.results.sort( (a, b) => b.createdAt.toNumber() - a.createdAt.toNumber(), ) setListingsToShow(sortedResults) } else if (filter === YOUR_LISTINGS) { const filteredListings = listings?.results.filter((listing) => { return listing.sellerAddress.toString() === publicKey?.toString() }) setListingsToShow(filteredListings) } else if (filter.includes('Price')) { return listings?.results.sort((a, b) => { const aPrice = toUiDecimals( a.price.basisPoints.toNumber(), MANGO_MINT_DECIMALS, ) const bPrice = toUiDecimals( b.price.basisPoints.toNumber(), MANGO_MINT_DECIMALS, ) return filter === PRICE_LOW_HIGH ? aPrice - bPrice : bPrice - aPrice }) } else { const filteredListings = listings?.results.filter((listing) => { const collectionName = listing.asset.json?.collection?.family || 'Unknown' return collectionName === filter }) setListingsToShow(filteredListings) } }, [listings, publicKey], ) const loading = loadingListings || fetchingListings return (

{`Filter Results`}

{asssetBidsModal && assetBidsListing ? ( ) : null}
{listingsToShow && listingsToShow.length ? ( listingsToShow.map((x, idx) => { const imgSource = x.asset.json?.image const nftBids = bids?.filter((bid) => bid.metadataAddress.equals(x.asset.metadataAddress), ) const bestBid = nftBids ? nftBids.reduce((a, c) => { const price = toUiDecimals( c.price.basisPoints.toNumber(), MANGO_MINT_DECIMALS, ) if (price > a) { a = price } return a }, 0) : 0 return (
{imgSource ? (
) : null}

{x.asset.json?.name || x.asset.name || 'Unknown'}

{x.asset.json?.collection?.family || 'Unknown'}

{formatNumericValue( toUiDecimals( x.price.basisPoints.toNumber(), MANGO_MINT_DECIMALS, ), )}{' '} MNGO

{bestBid ? `Best Offer: ${bestBid} MNGO` : 'No offers'}

{publicKey && !x.sellerAddress.equals(publicKey) && (
) : ( 'Buy Now' ) } colorClass="success" onClick={() => buyAsset(x)} /> openBidModal(x)} /> {bidNftModal && bidListing && ( )}
)} {publicKey && x.sellerAddress.equals(publicKey) && (
) : ( 'Delist' ) } colorClass="error" onClick={() => cancelListing(x)} /> openBidsModal(x)} />
)}
) }) ) : loading ? ( [...Array(4)].map((x, i) => (
)) ) : (
)}
{/*
*/}
) } export default ListingsView