feat: [info] add new stats box (#7522)
* feat: [info] add new stats section, wip * add stats section * implement fdv and market cap * use fdv from backend gql * code cleanup * update cypress tests * should only wrap if screen width <= 640 * minor design nits * remove sitemap change * nit pr review
This commit is contained in:
parent
098c7b9cbe
commit
5cbc56cf65
@ -1,4 +1,5 @@
|
||||
import { ChainId, WETH9 } from '@uniswap/sdk-core'
|
||||
import { FeatureFlag } from 'featureFlags'
|
||||
|
||||
import { ARB, UNI } from '../../src/constants/tokens'
|
||||
import { getTestSelector } from '../utils'
|
||||
@ -14,8 +15,9 @@ describe('Token details', () => {
|
||||
|
||||
it('Uniswap token should have all information populated', () => {
|
||||
// Uniswap token
|
||||
cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`)
|
||||
|
||||
cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`, {
|
||||
featureFlags: [{ name: FeatureFlag.infoTDP, value: false }],
|
||||
})
|
||||
// Price chart should be filled in
|
||||
cy.get('[data-cy="chart-header"]').should('include.text', '$')
|
||||
cy.get('[data-cy="price-chart"]').should('exist')
|
||||
@ -47,6 +49,22 @@ describe('Token details', () => {
|
||||
cy.contains(UNI_ADDRESS).should('exist')
|
||||
})
|
||||
|
||||
it('Uniswap token should have correct stats boxes if infoTDP flag on', () => {
|
||||
// Uniswap token
|
||||
cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`, {
|
||||
featureFlags: [{ name: FeatureFlag.infoTDP, value: true }],
|
||||
})
|
||||
|
||||
// Stats should have: TVL, FDV, market cap, 24H volume
|
||||
cy.get(getTestSelector('token-details-stats')).should('exist')
|
||||
cy.get(getTestSelector('token-details-stats')).within(() => {
|
||||
cy.get('[data-cy="tvl"]').should('include.text', '$')
|
||||
cy.get('[data-cy="fdv"]').should('include.text', '$')
|
||||
cy.get('[data-cy="market-cap"]').should('include.text', '$')
|
||||
cy.get('[data-cy="volume-24h"]').should('include.text', '$')
|
||||
})
|
||||
})
|
||||
|
||||
it('token with warning and low trading volume should have all information populated', () => {
|
||||
// Null token created for this test, 0 trading volume and has warning modal
|
||||
cy.visit('/tokens/ethereum/0x1eFBB78C8b917f67986BcE54cE575069c0143681')
|
||||
|
@ -2,6 +2,8 @@ import { Trans } from '@lingui/macro'
|
||||
import { ChainId } from '@uniswap/sdk-core'
|
||||
import { MouseoverTooltip } from 'components/Tooltip'
|
||||
import { getChainInfo } from 'constants/chainInfo'
|
||||
import { useInfoTDPEnabled } from 'featureFlags/flags/infoTDP'
|
||||
import { TokenQueryData } from 'graphql/data/Token'
|
||||
import { ReactNode } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { ExternalLink, ThemedText } from 'theme/components'
|
||||
@ -15,9 +17,13 @@ import { HEADER_DESCRIPTIONS } from '../TokenTable/TokenRow'
|
||||
export const StatWrapper = styled.div`
|
||||
color: ${({ theme }) => theme.neutral2};
|
||||
font-size: 14px;
|
||||
min-width: 168px;
|
||||
min-width: 121px;
|
||||
flex: 1;
|
||||
padding: 24px 0px;
|
||||
|
||||
@media screen and (max-width: ${({ theme }) => theme.breakpoint.sm}px) {
|
||||
min-width: 168px;
|
||||
}
|
||||
`
|
||||
const TokenStatsSection = styled.div`
|
||||
display: flex;
|
||||
@ -77,44 +83,100 @@ function Stat({
|
||||
type StatsSectionProps = {
|
||||
chainId: ChainId
|
||||
address: string
|
||||
priceLow52W?: NumericStat
|
||||
priceHigh52W?: NumericStat
|
||||
TVL?: NumericStat
|
||||
volume24H?: NumericStat
|
||||
tokenQueryData: TokenQueryData
|
||||
}
|
||||
export default function StatsSection(props: StatsSectionProps) {
|
||||
const { chainId, address, priceLow52W, priceHigh52W, TVL, volume24H } = props
|
||||
const { chainId, address, tokenQueryData } = props
|
||||
const { label, infoLink } = getChainInfo(chainId)
|
||||
const isInfoTDPEnabled = useInfoTDPEnabled()
|
||||
|
||||
if (TVL || volume24H || priceLow52W || priceHigh52W) {
|
||||
const tokenMarketInfo = tokenQueryData?.market
|
||||
const tokenProjectMarketInfo = tokenQueryData?.project?.markets?.[0] // aggregated market price from CoinGecko
|
||||
|
||||
const FDV = tokenProjectMarketInfo?.fullyDilutedValuation?.value
|
||||
const marketCap = tokenProjectMarketInfo?.marketCap?.value
|
||||
const TVL = tokenMarketInfo?.totalValueLocked?.value
|
||||
const volume24H = tokenMarketInfo?.volume24H?.value
|
||||
const priceHigh52W = tokenMarketInfo?.priceHigh52W?.value
|
||||
const priceLow52W = tokenMarketInfo?.priceLow52W?.value
|
||||
|
||||
const hasStats = isInfoTDPEnabled
|
||||
? TVL || FDV || marketCap || volume24H
|
||||
: TVL || volume24H || priceLow52W || priceHigh52W
|
||||
|
||||
if (hasStats) {
|
||||
return (
|
||||
<StatsWrapper data-testid="token-details-stats">
|
||||
<Header>
|
||||
<Trans>Stats</Trans>
|
||||
</Header>
|
||||
<TokenStatsSection>
|
||||
<StatPair>
|
||||
<Stat
|
||||
dataCy="tvl"
|
||||
value={TVL}
|
||||
description={HEADER_DESCRIPTIONS[TokenSortMethod.TOTAL_VALUE_LOCKED]}
|
||||
title={<Trans>TVL</Trans>}
|
||||
/>
|
||||
<Stat
|
||||
dataCy="volume-24h"
|
||||
value={volume24H}
|
||||
description={
|
||||
<Trans>
|
||||
24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours.
|
||||
</Trans>
|
||||
}
|
||||
title={<Trans>24H volume</Trans>}
|
||||
/>
|
||||
</StatPair>
|
||||
<StatPair>
|
||||
<Stat dataCy="52w-low" value={priceLow52W} title={<Trans>52W low</Trans>} />
|
||||
<Stat dataCy="52w-high" value={priceHigh52W} title={<Trans>52W high</Trans>} />
|
||||
</StatPair>
|
||||
{isInfoTDPEnabled ? (
|
||||
<>
|
||||
<StatPair>
|
||||
<Stat
|
||||
dataCy="tvl"
|
||||
value={TVL}
|
||||
description={HEADER_DESCRIPTIONS[TokenSortMethod.TOTAL_VALUE_LOCKED]}
|
||||
title={<Trans>TVL</Trans>}
|
||||
/>
|
||||
<Stat
|
||||
dataCy="market-cap"
|
||||
value={marketCap}
|
||||
description={
|
||||
<Trans>
|
||||
Market capitalization is the total market value of an asset's circulating supply.
|
||||
</Trans>
|
||||
}
|
||||
title={<Trans>Market cap</Trans>}
|
||||
/>
|
||||
</StatPair>
|
||||
<StatPair>
|
||||
<Stat
|
||||
dataCy="fdv"
|
||||
value={FDV}
|
||||
description={HEADER_DESCRIPTIONS[TokenSortMethod.FULLY_DILUTED_VALUATION]}
|
||||
title={<Trans>FDV</Trans>}
|
||||
/>
|
||||
<Stat
|
||||
dataCy="volume-24h"
|
||||
value={volume24H}
|
||||
description={
|
||||
<Trans>
|
||||
1 day volume is the amount of the asset that has been traded on Uniswap v3 during the past 24
|
||||
hours.
|
||||
</Trans>
|
||||
}
|
||||
title={<Trans>1 day volume</Trans>}
|
||||
/>
|
||||
</StatPair>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<StatPair>
|
||||
<Stat
|
||||
dataCy="tvl"
|
||||
value={TVL}
|
||||
description={HEADER_DESCRIPTIONS[TokenSortMethod.TOTAL_VALUE_LOCKED]}
|
||||
title={<Trans>TVL</Trans>}
|
||||
/>
|
||||
<Stat
|
||||
dataCy="volume-24h"
|
||||
value={volume24H}
|
||||
description={
|
||||
<Trans>
|
||||
24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours.
|
||||
</Trans>
|
||||
}
|
||||
title={<Trans>24H volume</Trans>}
|
||||
/>
|
||||
</StatPair>
|
||||
<StatPair>
|
||||
<Stat dataCy="52w-low" value={priceLow52W} title={<Trans>52W low</Trans>} />
|
||||
<Stat dataCy="52w-high" value={priceHigh52W} title={<Trans>52W high</Trans>} />
|
||||
</StatPair>
|
||||
</>
|
||||
)}
|
||||
</TokenStatsSection>
|
||||
</StatsWrapper>
|
||||
)
|
||||
|
@ -237,14 +237,7 @@ export default function TokenDetails({
|
||||
</TokenInfoContainer>
|
||||
<ChartSection tokenPriceQuery={tokenPriceQuery} onChangeTimePeriod={onChangeTimePeriod} />
|
||||
|
||||
<StatsSection
|
||||
chainId={pageChainId}
|
||||
address={address}
|
||||
TVL={tokenQueryData?.market?.totalValueLocked?.value}
|
||||
volume24H={tokenQueryData?.market?.volume24H?.value}
|
||||
priceHigh52W={tokenQueryData?.market?.priceHigh52W?.value}
|
||||
priceLow52W={tokenQueryData?.market?.priceLow52W?.value}
|
||||
/>
|
||||
<StatsSection chainId={pageChainId} address={address} tokenQueryData={tokenQueryData} />
|
||||
<Hr />
|
||||
<AboutSection
|
||||
address={address}
|
||||
|
@ -304,6 +304,12 @@ export const HEADER_DESCRIPTIONS: Record<TokenSortMethod, ReactNode | undefined>
|
||||
Total value locked (TVL) is the aggregate amount of the asset available across all Uniswap v3 liquidity pools.
|
||||
</Trans>
|
||||
),
|
||||
[TokenSortMethod.FULLY_DILUTED_VALUATION]: (
|
||||
<Trans>
|
||||
Fully diluted valuation (FDV) is the market capitalization of an asset if maximum token supply were in
|
||||
circulation.
|
||||
</Trans>
|
||||
),
|
||||
[TokenSortMethod.VOLUME]: (
|
||||
<Trans>Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame.</Trans>
|
||||
),
|
||||
|
@ -4,6 +4,7 @@ import { atomWithReset } from 'jotai/utils'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
export enum TokenSortMethod {
|
||||
FULLY_DILUTED_VALUATION = 'FDV',
|
||||
PRICE = 'Price',
|
||||
PERCENT_CHANGE = 'Change',
|
||||
TOTAL_VALUE_LOCKED = 'TVL',
|
||||
|
@ -58,6 +58,18 @@ gql`
|
||||
chain
|
||||
address
|
||||
}
|
||||
markets(currencies: [USD]) {
|
||||
fullyDilutedValuation {
|
||||
id
|
||||
value
|
||||
currency
|
||||
}
|
||||
marketCap {
|
||||
id
|
||||
value
|
||||
currency
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user