import { useCollections, useDynamicTokens } from '@reservoir0x/reservoir-kit-ui' import CollectionActions from 'components/collections/CollectionActions' import TokenCard from 'components/collections/TokenCard' import { Box, Flex, Text } from 'components/primitives' import { useChainCurrency, useMarketplaceChain } from 'hooks' import { useRouter } from 'next/router' import { FC, useState, useRef, useEffect } from 'react' import ReactMarkdown from 'react-markdown' import { styled } from 'stitches.config' import optimizeImage from 'utils/optimizeImage' import titleCase from 'utils/titleCase' import { truncateAddress } from 'utils/truncate' import supportedChains, { DefaultChain } from 'utils/chains' const StyledImage = styled('img', {}) const ItemGrid = styled(Box, { width: '100%', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '$4', '@md': { gridTemplateColumns: 'repeat(4, 1fr)', }, '@bp1500': { gridTemplateColumns: 'repeat(5, 1fr)', }, }) type Props = { collection?: ReturnType['data'][0] collectionId?: string tokens: ReturnType['data'] } export const CollectionDetails: FC = ({ collection, collectionId, tokens, }) => { const router = useRouter() const [descriptionExpanded, setDescriptionExpanded] = useState(false) const [isOverflowed, setIsOverflowed] = useState(false) const chainCurrency = useChainCurrency() const descriptionRef = useRef(null as any) const hasSecurityConfig = collection?.securityConfig && Object.values(collection.securityConfig).some(Boolean) const contractKind = `${collection?.contractKind?.toUpperCase()}${ hasSecurityConfig ? 'C' : '' }` const collectionChain = supportedChains.find( (chain) => router.query?.chain === chain.routePrefix ) || DefaultChain let creatorRoyalties = collection?.royalties?.bps ? collection?.royalties?.bps * 0.01 : 0 let chainName = collectionChain?.name let rareTokenQuery: Parameters['0'] = { limit: 8, collection: collectionId, includeLastSale: true, sortBy: 'rarity', sortDirection: 'asc', } useEffect(() => { setIsOverflowed( descriptionRef?.current?.scrollHeight > descriptionRef?.current?.clientHeight ) }, [isOverflowed, descriptionRef]) const { data: rareTokens } = useDynamicTokens(rareTokenQuery) return ( a > div > img': { transform: 'scale(1.1)', }, '@sm': { '&:hover .token-button-container': { bottom: 0, }, }, }} > {collection?.banner ? ( ) : null} About {collection?.name} { if (!ref) return descriptionRef.current = ref }} css={{ lineHeight: 1.5, display: '-webkit-box', WebkitLineClamp: descriptionExpanded ? 'reset' : 4, WebkitBoxOrient: 'vertical', overflow: 'hidden', textOverflow: 'ellipsis', }} > {isOverflowed && ( setDescriptionExpanded(!descriptionExpanded)} style="body1" as="p" css={{ cursor: 'pointer', mt: '$2', fontWeight: 600, textDecoration: 'underline', }} > {descriptionExpanded ? 'Close' : 'Expand'} )} {collection && } Collection Details {[ { label: 'Contract', value: truncateAddress(collection?.primaryContract || ''), }, { label: 'Token Standard', value: contractKind }, { label: 'Chain', value: chainName }, { label: 'Creator Earning', value: creatorRoyalties + '%', }, { label: 'Total Supply', value: collection?.tokenCount }, ].map((data) => ( {data.label} {data.value} ))} Collection Stats {[ { name: 'Floor', value: collection?.floorAsk?.price?.amount?.decimal ? `${collection?.floorAsk?.price?.amount?.decimal} ${collection?.floorAsk?.price?.currency?.symbol}` : '-', }, { name: 'Top Bid', value: collection?.topBid?.price?.amount?.decimal ? `${collection?.topBid?.price?.amount?.decimal || 0} ${ collection?.topBid?.price?.currency?.symbol }` : '-', }, { name: '24h Volume', value: `${Number( collection?.volume?.['1day']?.toFixed(2) ).toLocaleString()} ${chainCurrency.symbol}`, }, { name: '24h Sales', value: Number( `${collection?.salesCount?.['1day'] || 0}` ).toLocaleString(), }, ].map((stat) => ( {stat.name} {stat.value} ))} Rare Tokens {rareTokens.length > 0 ? ( {rareTokens.slice(0, 4).map((token) => ( ))} ) : ( No rare tokens )} Floor Tokens {rareTokens.length > 0 ? ( {tokens.slice(0, 4).map((token) => ( ))} ) : ( No Tokens )} ) }