react-feather#PlusCircle JavaScript Examples
The following examples show how to use
react-feather#PlusCircle.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PairPage.js From spooky-info with GNU General Public License v3.0 | 4 votes |
function PairPage({ pairAddress, history }) {
const {
token0,
token1,
reserve0,
reserve1,
reserveUSD,
trackedReserveUSD,
oneDayVolumeUSD,
volumeChangeUSD,
oneDayVolumeUntracked,
volumeChangeUntracked,
liquidityChangeUSD,
} = usePairData(pairAddress)
useEffect(() => {
document.querySelector('body').scrollTo(0, 0)
}, [])
const transactions = usePairTransactions(pairAddress)
const backgroundColor = useColor(pairAddress)
const formattedLiquidity = reserveUSD ? formattedNum(reserveUSD, true) : formattedNum(trackedReserveUSD, true)
const usingUntrackedLiquidity = !trackedReserveUSD && !!reserveUSD
const liquidityChange = formattedPercent(liquidityChangeUSD)
// volume
const volume = !!oneDayVolumeUSD ? formattedNum(oneDayVolumeUSD, true) : formattedNum(oneDayVolumeUntracked, true)
const usingUtVolume = oneDayVolumeUSD === 0 && !!oneDayVolumeUntracked
const volumeChange = formattedPercent(!usingUtVolume ? volumeChangeUSD : volumeChangeUntracked)
const showUSDWaning = usingUntrackedLiquidity | usingUtVolume
// get fees // get fees
const fees =
oneDayVolumeUSD || oneDayVolumeUSD === 0
? usingUtVolume
? formattedNum(oneDayVolumeUntracked * 0.002, true)
: formattedNum(oneDayVolumeUSD * 0.002, true)
: '-'
// token data for usd
const [ethPrice] = useEthPrice()
const token0USD =
token0?.derivedETH && ethPrice ? formattedNum(parseFloat(token0.derivedETH) * parseFloat(ethPrice), true) : ''
const token1USD =
token1?.derivedETH && ethPrice ? formattedNum(parseFloat(token1.derivedETH) * parseFloat(ethPrice), true) : ''
// rates
const token0Rate = reserve0 && reserve1 ? formattedNum(reserve1 / reserve0) : '-'
const token1Rate = reserve0 && reserve1 ? formattedNum(reserve0 / reserve1) : '-'
// formatted symbols for overflow
const formattedSymbol0 = token0?.symbol.length > 6 ? token0?.symbol.slice(0, 5) + '...' : token0?.symbol
const formattedSymbol1 = token1?.symbol.length > 6 ? token1?.symbol.slice(0, 5) + '...' : token1?.symbol
const below1080 = useMedia('(max-width: 1080px)')
const below900 = useMedia('(max-width: 900px)')
const below600 = useMedia('(max-width: 600px)')
const [dismissed, markAsDismissed] = usePathDismissed(history.location.pathname)
useEffect(() => {
window.scrollTo({
behavior: 'smooth',
top: 0,
})
}, [])
const [savedPairs, addPair] = useSavedPairs()
const listedTokens = useListedTokens()
if (PAIR_BLACKLIST.includes(pairAddress)) {
return (
<BlockedWrapper>
<BlockedMessageWrapper>
<AutoColumn gap="1rem" justify="center">
<TYPE.light style={{ textAlign: 'center' }}>
{BLOCKED_WARNINGS[pairAddress] ?? `This pair is not supported.`}
</TYPE.light>
<Link external={true} href={'https://ftmscan.com/address/' + pairAddress}>{`More about ${shortenAddress(
pairAddress
)}`}</Link>
</AutoColumn>
</BlockedMessageWrapper>
</BlockedWrapper>
)
}
return (
<PageWrapper>
<ThemedBackground backgroundColor={transparentize(0.6, backgroundColor)} />
<span />
<Warning
type={'pair'}
show={!dismissed && listedTokens && !(listedTokens.includes(token0?.id) && listedTokens.includes(token1?.id))}
setShow={markAsDismissed}
address={pairAddress}
/>
<ContentWrapperLarge>
<RowBetween>
<TYPE.body>
<BasicLink to="/pairs">{'Pairs '}</BasicLink>→ {token0?.symbol}-{token1?.symbol}
</TYPE.body>
{!below600 && <Search small={true} />}
</RowBetween>
<WarningGrouping
disabled={
!dismissed && listedTokens && !(listedTokens.includes(token0?.id) && listedTokens.includes(token1?.id))
}
>
<DashboardWrapper>
<AutoColumn gap="40px" style={{ marginBottom: '1.5rem' }}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
flexWrap: 'wrap',
width: '100%',
}}
>
<RowFixed style={{ flexWrap: 'wrap', minWidth: '100px' }}>
<RowFixed>
{token0 && token1 && (
<DoubleTokenLogo a0={token0?.id || ''} a1={token1?.id || ''} size={32} margin={true} />
)}{' '}
<TYPE.main fontSize={below1080 ? '1.5rem' : '2rem'} style={{ margin: '0 1rem' }}>
{token0 && token1 ? (
<>
<HoverSpan onClick={() => history.push(`/token/${token0?.id}`)}>{token0.symbol}</HoverSpan>
<span>-</span>
<HoverSpan onClick={() => history.push(`/token/${token1?.id}`)}>
{token1.symbol}
</HoverSpan>{' '}
Pair
</>
) : (
''
)}
</TYPE.main>
</RowFixed>
</RowFixed>
<RowFixed
ml={below900 ? '0' : '2.5rem'}
mt={below1080 && '1rem'}
style={{
flexDirection: below1080 ? 'row-reverse' : 'initial',
}}
>
{!!!savedPairs[pairAddress] && !below1080 ? (
<Hover onClick={() => addPair(pairAddress, token0.id, token1.id, token0.symbol, token1.symbol)}>
<StyledIcon>
<PlusCircle style={{ marginRight: '0.5rem' }} />
</StyledIcon>
</Hover>
) : !below1080 ? (
<StyledIcon>
<Bookmark style={{ marginRight: '0.5rem', opacity: 0.4 }} />
</StyledIcon>
) : (
<></>
)}
<Link external href={getPoolLink(token0?.id, token1?.id)}>
<ButtonLight color={backgroundColor}>+ Add Liquidity</ButtonLight>
</Link>
<Link external href={getSwapLink(token0?.id, token1?.id)}>
<ButtonDark ml={!below1080 && '.5rem'} mr={below1080 && '.5rem'} color={backgroundColor}>
Trade
</ButtonDark>
</Link>
</RowFixed>
</div>
</AutoColumn>
<AutoRow
gap="6px"
style={{
width: 'fit-content',
marginTop: below900 ? '1rem' : '0',
marginBottom: below900 ? '0' : '2rem',
flexWrap: 'wrap',
}}
>
<FixedPanel onClick={() => history.push(`/token/${token0?.id}`)}>
<RowFixed>
<TokenLogo address={token0?.id} size={'16px'} />
<TYPE.main fontSize={'16px'} lineHeight={1} fontWeight={500} ml={'4px'}>
{token0 && token1
? `1 ${formattedSymbol0} = ${token0Rate} ${formattedSymbol1} ${parseFloat(token0?.derivedETH) ? '(' + token0USD + ')' : ''
}`
: '-'}
</TYPE.main>
</RowFixed>
</FixedPanel>
<FixedPanel onClick={() => history.push(`/token/${token1?.id}`)}>
<RowFixed>
<TokenLogo address={token1?.id} size={'16px'} />
<TYPE.main fontSize={'16px'} lineHeight={1} fontWeight={500} ml={'4px'}>
{token0 && token1
? `1 ${formattedSymbol1} = ${token1Rate} ${formattedSymbol0} ${parseFloat(token1?.derivedETH) ? '(' + token1USD + ')' : ''
}`
: '-'}
</TYPE.main>
</RowFixed>
</FixedPanel>
</AutoRow>
<>
{!below1080 && (
<RowFixed>
<TYPE.main fontSize={'1.125rem'} mr="6px">
Pair Stats
</TYPE.main>
{showUSDWaning ? (
<HoverText text={UNTRACKED_COPY}>
<WarningIcon />
</HoverText>
) : null}
</RowFixed>
)}
<PanelWrapper style={{ marginTop: '1.5rem' }}>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Total Liquidity </TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{formattedLiquidity}
</TYPE.main>
<TYPE.main>{liquidityChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Volume (24hrs) </TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{volume}
</TYPE.main>
<TYPE.main>{volumeChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Fees (24hrs)</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{fees}
</TYPE.main>
<TYPE.main>{volumeChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Pooled Tokens</TYPE.main>
<div />
</RowBetween>
<Hover onClick={() => history.push(`/token/${token0?.id}`)} fade={true}>
<AutoRow gap="4px">
<TokenLogo address={token0?.id} />
<TYPE.main fontSize={20} lineHeight={1} fontWeight={500}>
<RowFixed>
{reserve0 ? formattedNum(reserve0) : ''}{' '}
<FormattedName text={token0?.symbol ?? ''} maxCharacters={8} margin={true} />
</RowFixed>
</TYPE.main>
</AutoRow>
</Hover>
<Hover onClick={() => history.push(`/token/${token1?.id}`)} fade={true}>
<AutoRow gap="4px">
<TokenLogo address={token1?.id} />
<TYPE.main fontSize={20} lineHeight={1} fontWeight={500}>
<RowFixed>
{reserve1 ? formattedNum(reserve1) : ''}{' '}
<FormattedName text={token1?.symbol ?? ''} maxCharacters={8} margin={true} />
</RowFixed>
</TYPE.main>
</AutoRow>
</Hover>
</AutoColumn>
</Panel>
<Panel
style={{
gridColumn: below1080 ? '1' : '2/4',
gridRow: below1080 ? '' : '1/5',
}}
>
<PairChart
address={pairAddress}
color={backgroundColor}
base0={reserve1 / reserve0}
base1={reserve0 / reserve1}
/>
</Panel>
</PanelWrapper>
<TYPE.main fontSize={'1.125rem'} style={{ marginTop: '3rem' }}>
Transactions
</TYPE.main>{' '}
<Panel
style={{
marginTop: '1.5rem',
}}
>
{transactions ? <TxnList transactions={transactions} /> : <Loader />}
</Panel>
<RowBetween style={{ marginTop: '3rem' }}>
<TYPE.main fontSize={'1.125rem'}>Pair Information</TYPE.main>{' '}
</RowBetween>
<Panel
rounded
style={{
marginTop: '1.5rem',
}}
p={20}
>
<TokenDetailsLayout>
<Column>
<TYPE.main>Pair Name</TYPE.main>
<TYPE.main style={{ marginTop: '.5rem' }}>
<RowFixed>
<FormattedName text={token0?.symbol ?? ''} maxCharacters={8} />
-
<FormattedName text={token1?.symbol ?? ''} maxCharacters={8} />
</RowFixed>
</TYPE.main>
</Column>
<Column>
<TYPE.main>Pair Address</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }}>
{pairAddress.slice(0, 6) + '...' + pairAddress.slice(38, 42)}
</TYPE.main>
<CopyHelper toCopy={pairAddress} />
</AutoRow>
</Column>
<Column>
<TYPE.main>
<RowFixed>
<FormattedName text={token0?.symbol ?? ''} maxCharacters={8} />{' '}
<span style={{ marginLeft: '4px' }}>Address</span>
</RowFixed>
</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }}>
{token0 && token0.id.slice(0, 6) + '...' + token0.id.slice(38, 42)}
</TYPE.main>
<CopyHelper toCopy={token0?.id} />
</AutoRow>
</Column>
<Column>
<TYPE.main>
<RowFixed>
<FormattedName text={token1?.symbol ?? ''} maxCharacters={8} />{' '}
<span style={{ marginLeft: '4px' }}>Address</span>
</RowFixed>
</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }} fontSize={16}>
{token1 && token1.id.slice(0, 6) + '...' + token1.id.slice(38, 42)}
</TYPE.main>
<CopyHelper toCopy={token1?.id} />
</AutoRow>
</Column>
<ButtonLight color={backgroundColor}>
<Link color={backgroundColor} external href={'https://ftmscan.com/address/' + pairAddress}>
View on FTMscan ↗
</Link>
</ButtonLight>
</TokenDetailsLayout>
</Panel>
</>
</DashboardWrapper>
</WarningGrouping>
</ContentWrapperLarge>
</PageWrapper>
)
}
Example #2
Source File: TokenPage.js From spooky-info with GNU General Public License v3.0 | 4 votes |
function TokenPage({ address, history }) {
const {
id,
name,
symbol,
priceUSD,
oneDayVolumeUSD,
totalLiquidityUSD,
volumeChangeUSD,
oneDayVolumeUT,
volumeChangeUT,
priceChangeUSD,
liquidityChangeUSD,
oneDayTxns,
txnChange,
} = useTokenData(address)
useEffect(() => {
document.querySelector('body').scrollTo(0, 0)
}, [])
// detect color from token
const backgroundColor = useColor(id, symbol)
const allPairs = useTokenPairs(address)
// pairs to show in pair list
const fetchedPairsList = useDataForList(allPairs)
// all transactions with this token
const transactions = useTokenTransactions(address)
// price
const price = priceUSD ? formattedNum(priceUSD, true) : ''
const priceChange = priceChangeUSD ? formattedPercent(priceChangeUSD) : ''
// volume
const volume = formattedNum(!!oneDayVolumeUSD ? oneDayVolumeUSD : oneDayVolumeUT, true)
const usingUtVolume = oneDayVolumeUSD === 0 && !!oneDayVolumeUT
const volumeChange = formattedPercent(!usingUtVolume ? volumeChangeUSD : volumeChangeUT)
// liquidity
const liquidity = formattedNum(totalLiquidityUSD, true)
const liquidityChange = formattedPercent(liquidityChangeUSD)
// transactions
const txnChangeFormatted = formattedPercent(txnChange)
const below1080 = useMedia('(max-width: 1080px)')
const below800 = useMedia('(max-width: 800px)')
const below600 = useMedia('(max-width: 600px)')
const below500 = useMedia('(max-width: 500px)')
// format for long symbol
const LENGTH = below1080 ? 10 : 16
const formattedSymbol = symbol?.length > LENGTH ? symbol.slice(0, LENGTH) + '...' : symbol
const [dismissed, markAsDismissed] = usePathDismissed(history.location.pathname)
const [savedTokens, addToken] = useSavedTokens()
const listedTokens = useListedTokens()
useEffect(() => {
window.scrollTo({
behavior: 'smooth',
top: 0,
})
}, [])
const [useTracked, setUseTracked] = useState(true)
if (TOKEN_BLACKLIST.includes(address)) {
return (
<BlockedWrapper>
<BlockedMessageWrapper>
<AutoColumn gap="1rem" justify="center">
<TYPE.light style={{ textAlign: 'center' }}>
{BLOCKED_WARNINGS[address] ?? `This token is not supported.`}
</TYPE.light>
<Link external={true} href={'https://ftmscan.com/address/' + address}>{`More about ${shortenAddress(
address
)}`}</Link>
</AutoColumn>
</BlockedMessageWrapper>
</BlockedWrapper>
)
}
return (
<PageWrapper>
<ThemedBackground backgroundColor={transparentize(0.6, backgroundColor)} />
<Warning
type={'token'}
show={!dismissed && listedTokens && !listedTokens.includes(address)}
setShow={markAsDismissed}
address={address}
/>
<ContentWrapper>
<RowBetween style={{ flexWrap: 'wrap', alingItems: 'start' }}>
<AutoRow align="flex-end" style={{ width: 'fit-content' }}>
<TYPE.body>
<BasicLink to="/tokens">{'Tokens '}</BasicLink>→ {symbol}
</TYPE.body>
<Link
style={{ width: 'fit-content' }}
color={backgroundColor}
external
href={'https://ftmscan.com/address/' + address}
>
<Text style={{ marginLeft: '.15rem' }} fontSize={'14px'} fontWeight={400}>
({address.slice(0, 8) + '...' + address.slice(36, 42)})
</Text>
</Link>
</AutoRow>
{!below600 && <Search small={true} />}
</RowBetween>
<WarningGrouping disabled={!dismissed && listedTokens && !listedTokens.includes(address)}>
<DashboardWrapper style={{ marginTop: below1080 ? '0' : '1rem' }}>
<RowBetween
style={{
flexWrap: 'wrap',
marginBottom: '2rem',
alignItems: 'flex-start',
}}
>
<RowFixed style={{ flexWrap: 'wrap' }}>
<RowFixed style={{ alignItems: 'baseline' }}>
<TokenLogo address={address} size="32px" style={{ alignSelf: 'center' }} />
<TYPE.main fontSize={below1080 ? '1.5rem' : '2rem'} fontWeight={500} style={{ margin: '0 1rem' }}>
<RowFixed gap="6px">
<FormattedName text={name ? name + ' ' : ''} maxCharacters={16} style={{ marginRight: '6px' }} />{' '}
{formattedSymbol ? `(${formattedSymbol})` : ''}
</RowFixed>
</TYPE.main>{' '}
{!below1080 && (
<>
<TYPE.main fontSize={'1.5rem'} fontWeight={500} style={{ marginRight: '1rem' }}>
{price}
</TYPE.main>
{priceChange}
</>
)}
</RowFixed>
</RowFixed>
<span>
<RowFixed ml={below500 ? '0' : '2.5rem'} mt={below500 ? '1rem' : '0'}>
{!!!savedTokens[address] && !below800 ? (
<Hover onClick={() => addToken(address, symbol)}>
<StyledIcon>
<PlusCircle style={{ marginRight: '0.5rem' }} />
</StyledIcon>
</Hover>
) : !below1080 ? (
<StyledIcon>
<Bookmark style={{ marginRight: '0.5rem', opacity: 0.4 }} />
</StyledIcon>
) : (
<></>
)}
<Link href={getPoolLink(address)} target="_blank">
<ButtonLight color={backgroundColor}>+ Add Liquidity</ButtonLight>
</Link>
<Link href={getSwapLink(address)} target="_blank">
<ButtonDark ml={'.5rem'} mr={below1080 && '.5rem'} color={backgroundColor}>
Trade
</ButtonDark>
</Link>
</RowFixed>
</span>
</RowBetween>
<>
{!below1080 && (
<RowFixed>
<TYPE.main fontSize={'1.125rem'} mr="6px">
Token Stats
</TYPE.main>
{usingUtVolume && (
<HoverText text={UNTRACKED_COPY}>
<WarningIcon />
</HoverText>
)}
</RowFixed>
)}
<PanelWrapper style={{ marginTop: below1080 ? '0' : '1rem' }}>
{below1080 && price && (
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Price</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
{' '}
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{price}
</TYPE.main>
<TYPE.main>{priceChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
)}
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Total Liquidity</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{liquidity}
</TYPE.main>
<TYPE.main>{liquidityChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Volume (24hrs)</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{volume}
</TYPE.main>
<TYPE.main>{volumeChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Transactions (24hrs)</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{oneDayTxns ? localNumber(oneDayTxns) : 0}
</TYPE.main>
<TYPE.main>{txnChangeFormatted}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel
style={{
gridColumn: below1080 ? '1' : '2/4',
gridRow: below1080 ? '' : '1/4',
}}
>
<TokenChart address={address} color={backgroundColor} base={priceUSD} />
</Panel>
</PanelWrapper>
</>
<RowBetween style={{ marginTop: '3rem' }}>
<TYPE.main fontSize={'1.125rem'}>Top Pairs</TYPE.main>
<AutoRow gap="4px" style={{ width: 'fit-content' }}>
<Checkbox
checked={useTracked}
setChecked={() => setUseTracked(!useTracked)}
text={'Hide untracked pairs'}
/>
<QuestionHelper text="USD amounts may be inaccurate in low liquidity pairs or pairs without ETH or stablecoins." />
</AutoRow>
</RowBetween>
<Panel
rounded
style={{
marginTop: '1.5rem',
padding: '1.125rem 0 ',
}}
>
{address && fetchedPairsList ? (
<PairList color={backgroundColor} address={address} pairs={fetchedPairsList} useTracked={useTracked} />
) : (
<Loader />
)}
</Panel>
<RowBetween mt={40} mb={'1rem'}>
<TYPE.main fontSize={'1.125rem'}>Transactions</TYPE.main> <div />
</RowBetween>
<Panel rounded>
{transactions ? <TxnList color={backgroundColor} transactions={transactions} /> : <Loader />}
</Panel>
<>
<RowBetween style={{ marginTop: '3rem' }}>
<TYPE.main fontSize={'1.125rem'}>Token Information</TYPE.main>{' '}
</RowBetween>
<Panel
rounded
style={{
marginTop: '1.5rem',
}}
p={20}
>
<TokenDetailsLayout>
<Column>
<TYPE.main>Symbol</TYPE.main>
<Text style={{ marginTop: '.5rem' }} fontSize={24} fontWeight="500">
<FormattedName text={symbol} maxCharacters={12} />
</Text>
</Column>
<Column>
<TYPE.main>Name</TYPE.main>
<TYPE.main style={{ marginTop: '.5rem' }} fontSize={24} fontWeight="500">
<FormattedName text={name} maxCharacters={16} />
</TYPE.main>
</Column>
<Column>
<TYPE.main>Address</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }} fontSize={24} fontWeight="500">
{address.slice(0, 8) + '...' + address.slice(36, 42)}
</TYPE.main>
<CopyHelper toCopy={address} />
</AutoRow>
</Column>
<ButtonLight color={backgroundColor}>
<Link color={backgroundColor} external href={'https://ftmscan.com/address/' + address}>
View on FTMscan ↗
</Link>
</ButtonLight>
</TokenDetailsLayout>
</Panel>
</>
</DashboardWrapper>
</WarningGrouping>
</ContentWrapper>
</PageWrapper>
)
}
Example #3
Source File: PairPage.js From pancake-info-v1 with GNU General Public License v3.0 | 4 votes |
function PairPage({ pairAddress, history }) {
const {
token0,
token1,
reserve0,
reserve1,
reserveUSD,
trackedReserveUSD,
oneDayVolumeUSD,
volumeChangeUSD,
oneDayVolumeUntracked,
volumeChangeUntracked,
liquidityChangeUSD,
} = usePairData(pairAddress)
useEffect(() => {
document.querySelector('body').scrollTo(0, 0)
}, [])
const transactions = usePairTransactions(pairAddress)
const backgroundColor = useColor(pairAddress)
// liquidity
const liquidity = trackedReserveUSD
? formattedNum(trackedReserveUSD, true)
: reserveUSD
? formattedNum(reserveUSD, true)
: '-'
const liquidityChange = formattedPercent(liquidityChangeUSD)
// mark if using untracked liquidity
const [usingTracked, setUsingTracked] = useState(true)
useEffect(() => {
setUsingTracked(!trackedReserveUSD ? false : true)
}, [trackedReserveUSD])
// volume // volume
const volume =
oneDayVolumeUSD || oneDayVolumeUSD === 0
? formattedNum(oneDayVolumeUSD === 0 ? oneDayVolumeUntracked : oneDayVolumeUSD, true)
: oneDayVolumeUSD === 0
? '$0'
: '-'
// mark if using untracked volume
const [usingUtVolume, setUsingUtVolume] = useState(false)
useEffect(() => {
setUsingUtVolume(oneDayVolumeUSD === 0 ? true : false)
}, [oneDayVolumeUSD])
const volumeChange = formattedPercent(!usingUtVolume ? volumeChangeUSD : volumeChangeUntracked)
// get fees // get fees
const fees =
oneDayVolumeUSD || oneDayVolumeUSD === 0
? usingUtVolume
? formattedNum(oneDayVolumeUntracked * 0.002, true)
: formattedNum(oneDayVolumeUSD * 0.002, true)
: '-'
// token data for usd
const [ethPrice] = useEthPrice()
const token0USD =
token0?.derivedETH && ethPrice ? formattedNum(parseFloat(token0.derivedETH) * parseFloat(ethPrice), true) : ''
const token1USD =
token1?.derivedETH && ethPrice ? formattedNum(parseFloat(token1.derivedETH) * parseFloat(ethPrice), true) : ''
// rates
const token0Rate = reserve0 && reserve1 ? formattedNum(reserve1 / reserve0) : '-'
const token1Rate = reserve0 && reserve1 ? formattedNum(reserve0 / reserve1) : '-'
// formatted symbols for overflow
const formattedSymbol0 = token0?.symbol.length > 6 ? token0?.symbol.slice(0, 5) + '...' : token0?.symbol
const formattedSymbol1 = token1?.symbol.length > 6 ? token1?.symbol.slice(0, 5) + '...' : token1?.symbol
const below1080 = useMedia('(max-width: 1080px)')
const below900 = useMedia('(max-width: 900px)')
const below600 = useMedia('(max-width: 600px)')
const [dismissed, markAsDismissed] = usePathDismissed(history.location.pathname)
useEffect(() => {
window.scrollTo({
behavior: 'smooth',
top: 0,
})
}, [])
const [savedPairs, addPair] = useSavedPairs()
const listedTokens = useListedTokens()
return (
<PageWrapper>
<ThemedBackground backgroundColor={transparentize(0.6, backgroundColor)} />
<span />
<Warning
type={'pair'}
show={!dismissed && listedTokens && !(listedTokens.includes(token0?.id) && listedTokens.includes(token1?.id))}
setShow={markAsDismissed}
address={pairAddress}
/>
<ContentWrapperLarge>
<RowBetween>
<TYPE.body>
<BasicLink to="/pairs">{'Pairs '}</BasicLink>→ {token0?.symbol}-{token1?.symbol}
</TYPE.body>
{!below600 && <Search small={true} />}
</RowBetween>
<WarningGrouping
disabled={
!dismissed && listedTokens && !(listedTokens.includes(token0?.id) && listedTokens.includes(token1?.id))
}
>
<DashboardWrapper>
<AutoColumn gap="40px" style={{ marginBottom: '1.5rem' }}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
flexWrap: 'wrap',
width: '100%',
}}
>
<RowFixed style={{ flexWrap: 'wrap', minWidth: '100px' }}>
<RowFixed>
{token0 && token1 && (
<DoubleTokenLogo a0={token0?.id || ''} a1={token1?.id || ''} size={32} margin={true} />
)}{' '}
<TYPE.main fontSize={below1080 ? '1.5rem' : '2rem'} style={{ margin: '0 1rem' }}>
{token0 && token1 ? (
<>
<HoverSpan onClick={() => history.push(`/token/${token0?.id}`)}>{token0.symbol}</HoverSpan>
<span>-</span>
<HoverSpan onClick={() => history.push(`/token/${token1?.id}`)}>
{token1.symbol}
</HoverSpan>{' '}
Pair
</>
) : (
''
)}
</TYPE.main>
</RowFixed>
</RowFixed>
<RowFixed
ml={below900 ? '0' : '2.5rem'}
mt={below1080 && '1rem'}
style={{
flexDirection: below1080 ? 'row-reverse' : 'initial',
}}
>
{!!!savedPairs[pairAddress] && !below1080 ? (
<Hover onClick={() => addPair(pairAddress, token0.id, token1.id, token0.symbol, token1.symbol)}>
<StyledIcon>
<PlusCircle style={{ marginRight: '0.5rem' }} />
</StyledIcon>
</Hover>
) : !below1080 ? (
<StyledIcon>
<Bookmark style={{ marginRight: '0.5rem', opacity: 0.4 }} />
</StyledIcon>
) : (
<></>
)}
<Link external href={getPoolLink(token0?.id, token1?.id)}>
<ButtonLight color={backgroundColor}>+ Add Liquidity</ButtonLight>
</Link>
<Link external href={getSwapLink(token0?.id, token1?.id)}>
<ButtonDark ml={!below1080 && '.5rem'} mr={below1080 && '.5rem'} color={backgroundColor}>
Trade
</ButtonDark>
</Link>
</RowFixed>
</div>
</AutoColumn>
<AutoRow
gap="6px"
style={{
width: 'fit-content',
marginTop: below900 ? '1rem' : '0',
marginBottom: below900 ? '0' : '2rem',
flexWrap: 'wrap',
}}
>
<FixedPanel onClick={() => history.push(`/token/${token0?.id}`)}>
<RowFixed>
<TokenLogo address={token0?.id} size={'16px'} />
<TYPE.main fontSize={'16px'} lineHeight={1} fontWeight={500} ml={'4px'}>
{token0 && token1
? `1 ${formattedSymbol0} = ${token0Rate} ${formattedSymbol1} ${
parseFloat(token0?.derivedETH) ? '(' + token0USD + ')' : ''
}`
: '-'}
</TYPE.main>
</RowFixed>
</FixedPanel>
<FixedPanel onClick={() => history.push(`/token/${token1?.id}`)}>
<RowFixed>
<TokenLogo address={token1?.id} size={'16px'} />
<TYPE.main fontSize={'16px'} lineHeight={1} fontWeight={500} ml={'4px'}>
{token0 && token1
? `1 ${formattedSymbol1} = ${token1Rate} ${formattedSymbol0} ${
parseFloat(token1?.derivedETH) ? '(' + token1USD + ')' : ''
}`
: '-'}
</TYPE.main>
</RowFixed>
</FixedPanel>
</AutoRow>
<>
{!below1080 && <TYPE.main fontSize={'1.125rem'}>Pair Stats</TYPE.main>}
<PanelWrapper style={{ marginTop: '1.5rem' }}>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Total Liquidity {!usingTracked ? '(Untracked)' : ''}</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{liquidity}
</TYPE.main>
<TYPE.main>{liquidityChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Volume (24hrs) {usingUtVolume && '(Untracked)'}</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{volume}
</TYPE.main>
<TYPE.main>{volumeChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Fees (24hrs)</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{fees}
</TYPE.main>
<TYPE.main>{volumeChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel style={{ height: '100%' }}>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Pooled Tokens</TYPE.main>
<div />
</RowBetween>
<Hover onClick={() => history.push(`/token/${token0?.id}`)} fade={true}>
<AutoRow gap="4px">
<TokenLogo address={token0?.id} />
<TYPE.main fontSize={20} lineHeight={1} fontWeight={500}>
<RowFixed>
{reserve0 ? formattedNum(reserve0) : ''}{' '}
<FormattedName text={token0?.symbol ?? ''} maxCharacters={8} margin={true} />
</RowFixed>
</TYPE.main>
</AutoRow>
</Hover>
<Hover onClick={() => history.push(`/token/${token1?.id}`)} fade={true}>
<AutoRow gap="4px">
<TokenLogo address={token1?.id} />
<TYPE.main fontSize={20} lineHeight={1} fontWeight={500}>
<RowFixed>
{reserve1 ? formattedNum(reserve1) : ''}{' '}
<FormattedName text={token1?.symbol ?? ''} maxCharacters={8} margin={true} />
</RowFixed>
</TYPE.main>
</AutoRow>
</Hover>
</AutoColumn>
</Panel>
<Panel
style={{
gridColumn: below1080 ? '1' : '2/4',
gridRow: below1080 ? '' : '1/5',
}}
>
<PairChart
address={pairAddress}
color={backgroundColor}
base0={reserve1 / reserve0}
base1={reserve0 / reserve1}
/>
</Panel>
</PanelWrapper>
<TYPE.main fontSize={'1.125rem'} style={{ marginTop: '3rem' }}>
Transactions
</TYPE.main>{' '}
<Panel
style={{
marginTop: '1.5rem',
}}
>
{transactions ? <TxnList transactions={transactions} /> : <Loader />}
</Panel>
<RowBetween style={{ marginTop: '3rem' }}>
<TYPE.main fontSize={'1.125rem'}>Pair Information</TYPE.main>{' '}
</RowBetween>
<Panel
rounded
style={{
marginTop: '1.5rem',
}}
p={20}
>
<TokenDetailsLayout>
<Column>
<TYPE.main>Pair Name</TYPE.main>
<TYPE.main style={{ marginTop: '.5rem' }}>
<RowFixed>
<FormattedName text={token0?.symbol ?? ''} maxCharacters={8} />
-
<FormattedName text={token1?.symbol ?? ''} maxCharacters={8} />
</RowFixed>
</TYPE.main>
</Column>
<Column>
<TYPE.main>Pair Address</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }}>
{pairAddress.slice(0, 6) + '...' + pairAddress.slice(38, 42)}
</TYPE.main>
<CopyHelper toCopy={pairAddress} />
</AutoRow>
</Column>
<Column>
<TYPE.main>
<RowFixed>
<FormattedName text={token0?.symbol ?? ''} maxCharacters={8} />{' '}
<span style={{ marginLeft: '4px' }}>Address</span>
</RowFixed>
</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }}>
{token0 && token0.id.slice(0, 6) + '...' + token0.id.slice(38, 42)}
</TYPE.main>
<CopyHelper toCopy={token0?.id} />
</AutoRow>
</Column>
<Column>
<TYPE.main>
<RowFixed>
<FormattedName text={token1?.symbol ?? ''} maxCharacters={8} />{' '}
<span style={{ marginLeft: '4px' }}>Address</span>
</RowFixed>
</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }} fontSize={16}>
{token1 && token1.id.slice(0, 6) + '...' + token1.id.slice(38, 42)}
</TYPE.main>
<CopyHelper toCopy={token1?.id} />
</AutoRow>
</Column>
<ButtonLight color={backgroundColor}>
<Link color={backgroundColor} external href={'https://bscscan.com/address/' + pairAddress}>
View on BscScan ↗
</Link>
</ButtonLight>
</TokenDetailsLayout>
</Panel>
</>
</DashboardWrapper>
</WarningGrouping>
</ContentWrapperLarge>
</PageWrapper>
)
}
Example #4
Source File: TokenPage.js From pancake-info-v1 with GNU General Public License v3.0 | 4 votes |
function TokenPage({ address, history }) {
const {
id,
name,
symbol,
priceUSD,
oneDayVolumeUSD,
totalLiquidityUSD,
volumeChangeUSD,
oneDayVolumeUT,
volumeChangeUT,
priceChangeUSD,
liquidityChangeUSD,
oneDayTxns,
txnChange,
} = useTokenData(address)
useEffect(() => {
document.querySelector('body').scrollTo(0, 0)
}, [])
// detect color from token
const backgroundColor = useColor(id, symbol)
const allPairs = useTokenPairs(address)
// pairs to show in pair list
const fetchedPairsList = useDataForList(allPairs)
// all transactions with this token
const transactions = useTokenTransactions(address)
// price
const price = priceUSD ? formattedNum(priceUSD, true) : ''
const priceChange = priceChangeUSD ? formattedPercent(priceChangeUSD) : ''
// volume
const volume =
oneDayVolumeUSD || oneDayVolumeUSD === 0
? formattedNum(oneDayVolumeUSD === 0 ? oneDayVolumeUT : oneDayVolumeUSD, true)
: oneDayVolumeUSD === 0
? '$0'
: '-'
// mark if using untracked volume
const [usingUtVolume, setUsingUtVolume] = useState(false)
useEffect(() => {
setUsingUtVolume(oneDayVolumeUSD === 0 ? true : false)
}, [oneDayVolumeUSD])
const volumeChange = formattedPercent(!usingUtVolume ? volumeChangeUSD : volumeChangeUT)
// liquidity
const liquidity = totalLiquidityUSD ? formattedNum(totalLiquidityUSD, true) : totalLiquidityUSD === 0 ? '$0' : '-'
const liquidityChange = formattedPercent(liquidityChangeUSD)
// transactions
const txnChangeFormatted = formattedPercent(txnChange)
const below1080 = useMedia('(max-width: 1080px)')
const below800 = useMedia('(max-width: 800px)')
const below600 = useMedia('(max-width: 600px)')
const below500 = useMedia('(max-width: 500px)')
// format for long symbol
const LENGTH = below1080 ? 10 : 16
const formattedSymbol = symbol?.length > LENGTH ? symbol.slice(0, LENGTH) + '...' : symbol
const [dismissed, markAsDismissed] = usePathDismissed(history.location.pathname)
const [savedTokens, addToken] = useSavedTokens()
const listedTokens = useListedTokens()
useEffect(() => {
window.scrollTo({
behavior: 'smooth',
top: 0,
})
}, [])
return (
<PageWrapper>
<ThemedBackground backgroundColor={transparentize(0.6, backgroundColor)} />
<Warning
type={'token'}
show={!dismissed && listedTokens && !listedTokens.includes(address)}
setShow={markAsDismissed}
address={address}
/>
<ContentWrapper>
<RowBetween style={{ flexWrap: 'wrap', alingItems: 'start' }}>
<AutoRow align="flex-end" style={{ width: 'fit-content' }}>
<TYPE.body>
<BasicLink to="/tokens">{'Tokens '}</BasicLink>→ {symbol}
{' '}
</TYPE.body>
<Link
style={{ width: 'fit-content' }}
color={backgroundColor}
external
href={'https://bscscan.com/address/' + address}
>
<Text style={{ marginLeft: '.15rem' }} fontSize={'14px'} fontWeight={400}>
({address.slice(0, 8) + '...' + address.slice(36, 42)})
</Text>
</Link>
</AutoRow>
{!below600 && <Search small={true} />}
</RowBetween>
<WarningGrouping disabled={!dismissed && listedTokens && !listedTokens.includes(address)}>
<DashboardWrapper style={{ marginTop: below1080 ? '0' : '1rem' }}>
<RowBetween
style={{
flexWrap: 'wrap',
marginBottom: '2rem',
alignItems: 'flex-start',
}}
>
<RowFixed style={{ flexWrap: 'wrap' }}>
<RowFixed style={{ alignItems: 'baseline' }}>
<TokenLogo address={address} size="32px" style={{ alignSelf: 'center' }} />
<TYPE.main fontSize={below1080 ? '1.5rem' : '2rem'} fontWeight={500} style={{ margin: '0 1rem' }}>
<RowFixed gap="6px">
<FormattedName text={name ? name + ' ' : ''} maxCharacters={16} style={{ marginRight: '6px' }} />{' '}
{formattedSymbol ? `(${formattedSymbol})` : ''}
</RowFixed>
</TYPE.main>{' '}
{!below1080 && (
<>
<TYPE.main fontSize={'1.5rem'} fontWeight={500} style={{ marginRight: '1rem' }}>
{price}
</TYPE.main>
{priceChange}
</>
)}
</RowFixed>
</RowFixed>
<span>
<RowFixed ml={below500 ? '0' : '2.5rem'} mt={below500 ? '1rem' : '0'}>
{!!!savedTokens[address] && !below800 ? (
<Hover onClick={() => addToken(address, symbol)}>
<StyledIcon>
<PlusCircle style={{ marginRight: '0.5rem' }} />
</StyledIcon>
</Hover>
) : !below1080 ? (
<StyledIcon>
<Bookmark style={{ marginRight: '0.5rem', opacity: 0.4 }} />
</StyledIcon>
) : (
<></>
)}
<Link href={getPoolLink(address)} target="_blank">
<ButtonLight color={backgroundColor}>+ Add Liquidity</ButtonLight>
</Link>
<Link href={getSwapLink(address)} target="_blank">
<ButtonDark ml={'.5rem'} mr={below1080 && '.5rem'} color={backgroundColor}>
Trade
</ButtonDark>
</Link>
</RowFixed>
</span>
</RowBetween>
<>
<PanelWrapper style={{ marginTop: below1080 ? '0' : '1rem' }}>
{below1080 && price && (
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Price</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
{' '}
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{price}
</TYPE.main>
<TYPE.main>{priceChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
)}
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Total Liquidity</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{liquidity}
</TYPE.main>
<TYPE.main>{liquidityChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Volume (24hrs) {usingUtVolume && '(Untracked)'}</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{volume}
</TYPE.main>
<TYPE.main>{volumeChange}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel>
<AutoColumn gap="20px">
<RowBetween>
<TYPE.main>Transactions (24hrs)</TYPE.main>
<div />
</RowBetween>
<RowBetween align="flex-end">
<TYPE.main fontSize={'1.5rem'} lineHeight={1} fontWeight={500}>
{oneDayTxns ? localNumber(oneDayTxns) : oneDayTxns === 0 ? 0 : '-'}
</TYPE.main>
<TYPE.main>{txnChangeFormatted}</TYPE.main>
</RowBetween>
</AutoColumn>
</Panel>
<Panel
style={{
gridColumn: below1080 ? '1' : '2/4',
gridRow: below1080 ? '' : '1/4',
}}
>
<TokenChart address={address} color={backgroundColor} base={priceUSD} />
</Panel>
</PanelWrapper>
</>
<span>
<TYPE.main fontSize={'1.125rem'} style={{ marginTop: '3rem' }}>
Top Pairs
</TYPE.main>
</span>
<Panel
rounded
style={{
marginTop: '1.5rem',
padding: '1.125rem 0 ',
}}
>
{address && fetchedPairsList ? (
<PairList color={backgroundColor} address={address} pairs={fetchedPairsList} />
) : (
<Loader />
)}
</Panel>
<RowBetween mt={40} mb={'1rem'}>
<TYPE.main fontSize={'1.125rem'}>Transactions</TYPE.main> <div />
</RowBetween>
<Panel rounded>
{transactions ? <TxnList color={backgroundColor} transactions={transactions} /> : <Loader />}
</Panel>
<>
<RowBetween style={{ marginTop: '3rem' }}>
<TYPE.main fontSize={'1.125rem'}>Token Information</TYPE.main>{' '}
</RowBetween>
<Panel
rounded
style={{
marginTop: '1.5rem',
}}
p={20}
>
<TokenDetailsLayout>
<Column>
<TYPE.main>Symbol</TYPE.main>
<Text style={{ marginTop: '.5rem' }} fontSize={24} fontWeight="500">
<FormattedName text={symbol} maxCharacters={12} />
</Text>
</Column>
<Column>
<TYPE.main>Name</TYPE.main>
<TYPE.main style={{ marginTop: '.5rem' }} fontSize={24} fontWeight="500">
<FormattedName text={name} maxCharacters={16} />
</TYPE.main>
</Column>
<Column>
<TYPE.main>Address</TYPE.main>
<AutoRow align="flex-end">
<TYPE.main style={{ marginTop: '.5rem' }} fontSize={24} fontWeight="500">
{address.slice(0, 8) + '...' + address.slice(36, 42)}
</TYPE.main>
<CopyHelper toCopy={address} />
</AutoRow>
</Column>
<ButtonLight color={backgroundColor}>
<Link color={backgroundColor} external href={'https://bscscan.com/address/' + address}>
View on BscScan ↗
</Link>
</ButtonLight>
</TokenDetailsLayout>
</Panel>
</>
</DashboardWrapper>
</WarningGrouping>
</ContentWrapper>
</PageWrapper>
)
}