feat: [info] Add Stats Section to PDP (#7353)

* feat: setup initial pool details page and route

* add pool data query and call on enw page

* make query dynamic to url chainId

* Get and display Header info

* add token symbols

* split header into its own file

* add helper function to not default to eth chain

* add helper function tests

* add header component tests

* add mocked test for PDP

* use valid values

* allow unsupported BE chains supported by thegraph

* typecheck

* remove useless row

* no longer needed child

* use first and last child

* move mock consts to their own file

* skele linear task

* return null

* descriptiive pool not found bool

* modify correct logo container

* update snapshots

* instantiate all chain apollo clients

* added snapshot test

* merge main and update snapshots

* Update src/pages/PoolDetails/PoolDetailsHeader.tsx

Co-authored-by: Nate Wienert <natewienert@gmail.com>

* type feeTier

* setup init stats component

* correctly query pool data for t24, t48, and tWeek timestamps

* add comments

* sanitize pool data and update tests

* correct test data

* add todo

* lint

* show correct data

* remove logs

* use formatter

* showing colored bars

* styled graph

* get muted color

* refactor: move getColor to src

* refactor useColor to use getColor function

* remove consts

* refactor files

* 1st class var support courtesy of carter

* remove logging and adds comments

* mobile styling

* move Stats to its own file

* add test cases

* add test file

* update padding

* remove old test file

* respond to feedback

* right column wrapper

* update tests

---------

Co-authored-by: Nate Wienert <natewienert@gmail.com>
This commit is contained in:
Charles Bachmeier 2023-09-28 09:27:29 -07:00 committed by GitHub
parent 3bb55c6b5d
commit d63bdf1887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1396 additions and 4 deletions

@ -51,7 +51,7 @@ gql`
} }
` `
interface PoolData { export interface PoolData {
// basic token info // basic token info
address: string address: string
feeTier: number feeTier: number

@ -0,0 +1,37 @@
import { validPoolDataResponse } from 'test-utils/pools/fixtures'
import { render, screen } from 'test-utils/render'
import { BREAKPOINTS } from 'theme'
import { PoolDetailsStats } from './PoolDetailsStats'
describe('PoolDetailsStats', () => {
const mockProps = {
poolData: validPoolDataResponse.data,
isReversed: false,
chainId: 1,
}
it('renders stats text correctly', () => {
const { asFragment } = render(<PoolDetailsStats {...mockProps} />)
expect(asFragment()).toMatchSnapshot()
expect(screen.getByText(/Stats/i)).toBeInTheDocument()
expect(screen.getByText('90.93M USDC')).toBeInTheDocument()
expect(screen.getByText('82,526.49 WETH')).toBeInTheDocument()
expect(screen.getByText(/TVL/i)).toBeInTheDocument()
expect(screen.getByText('$223.2M')).toBeInTheDocument()
expect(screen.getByTestId('pool-balance-chart')).toBeInTheDocument()
})
it('pool balance chart not visible on mobile', () => {
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: BREAKPOINTS.md,
})
const { asFragment } = render(<PoolDetailsStats {...mockProps} />)
expect(asFragment()).toMatchSnapshot()
expect(screen.queryByTestId('pool-balance-chart')).toBeNull()
})
})

@ -0,0 +1,223 @@
import { Trans } from '@lingui/macro'
import Column from 'components/Column'
import CurrencyLogo from 'components/Logo/CurrencyLogo'
import Row from 'components/Row'
import { DeltaArrow, formatDelta } from 'components/Tokens/TokenDetails/Delta'
import { PoolData } from 'graphql/thegraph/PoolData'
import { useCurrency } from 'hooks/Tokens'
import { useColor } from 'hooks/useColor'
import { useScreenSize } from 'hooks/useScreenSize'
import { ReactNode, useMemo } from 'react'
import { Text } from 'rebass'
import styled, { css } from 'styled-components'
import { BREAKPOINTS } from 'theme'
import { ThemedText } from 'theme/components'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const HeaderText = styled(Text)`
font-weight: 485;
font-size: 24px;
line-height: 36px;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
width: 100%;
}
`
const StatsWrapper = styled(Column)`
gap: 24px;
padding: 20px;
border-radius: 20px;
background: ${({ theme }) => theme.surface2};
width: 100%;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
flex-direction: row;
background: ${({ theme }) => theme.surface1};
flex-wrap: wrap;
padding: 20px 0px;
justify-content: space-between;
}
`
const StatItemColumn = styled(Column)`
gap: 8px;
flex: 1;
min-width: 180px;
@media (max-width: ${BREAKPOINTS.sm}px) {
min-width: 150px;
}
`
const PoolBalanceSymbols = styled(Row)`
justify-content: space-between;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
flex-direction: column;
}
`
const PoolBalanceTokenNames = styled(Row)`
font-weight: 485;
font-size: 18px;
line-height: 24px;
width: max-content;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
font-size: 20px;
line-height: 28px;
width: 100%;
}
`
const leftBarChartStyles = css`
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-right: 1px solid ${({ theme }) => theme.surface2};
`
const rightBarChartStyles = css`
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
border-left: 1px solid ${({ theme }) => theme.surface2};
`
const BalanceChartSide = styled.div<{ percent: number; $color: string; isLeft: boolean }>`
height: 8px;
width: ${({ percent }) => percent * 100}%;
background: ${({ $color }) => $color};
${({ isLeft }) => (isLeft ? leftBarChartStyles : rightBarChartStyles)}
`
interface PoolDetailsStatsProps {
poolData: PoolData
isReversed: boolean
chainId?: number
}
export function PoolDetailsStats({ poolData, isReversed, chainId }: PoolDetailsStatsProps) {
const isScreenSize = useScreenSize()
const screenIsNotLarge = isScreenSize['lg']
const { formatNumber } = useFormatter()
const currency0 = useCurrency(poolData?.token0?.id, chainId) ?? undefined
const currency1 = useCurrency(poolData?.token1?.id, chainId) ?? undefined
const color0 = useColor(currency0?.wrapped)
const color1 = useColor(currency1?.wrapped)
const [token0, token1] = useMemo(() => {
const fullWidth = poolData?.tvlToken0 / poolData?.token0Price + poolData?.tvlToken1
const token0FullData = {
...poolData?.token0,
price: poolData?.token0Price,
tvl: poolData?.tvlToken0,
color: color0,
percent: poolData?.tvlToken0 / poolData?.token0Price / fullWidth,
currency: currency0,
}
const token1FullData = {
...poolData?.token1,
price: poolData?.token1Price,
tvl: poolData?.tvlToken1,
color: color1,
percent: poolData?.tvlToken1 / fullWidth,
currency: currency1,
}
return isReversed ? [token1FullData, token0FullData] : [token0FullData, token1FullData]
}, [color0, color1, currency0, currency1, isReversed, poolData])
return (
<StatsWrapper>
<HeaderText>
<Trans>Stats</Trans>
</HeaderText>
<StatItemColumn>
<ThemedText.BodySecondary>
<Trans>Pool balances</Trans>
</ThemedText.BodySecondary>
<PoolBalanceSymbols>
<PoolBalanceTokenNames>
{!screenIsNotLarge && (
<CurrencyLogo currency={token0.currency} size="20px" style={{ marginRight: '8px' }} />
)}
{formatNumber({
input: token0.tvl,
type: NumberType.TokenNonTx,
})}
&nbsp;
{token0.symbol}
</PoolBalanceTokenNames>
<PoolBalanceTokenNames>
{!screenIsNotLarge && (
<CurrencyLogo currency={token1.currency} size="20px" style={{ marginRight: '8px' }} />
)}
{formatNumber({
input: token1.tvl,
type: NumberType.TokenNonTx,
})}
&nbsp;
{token1.symbol}
</PoolBalanceTokenNames>
</PoolBalanceSymbols>
{screenIsNotLarge && (
<Row data-testid="pool-balance-chart">
{token0.color && <BalanceChartSide percent={token0.percent} $color={token0.color} isLeft={true} />}
{token1.color && <BalanceChartSide percent={token1.percent} $color={token1.color} isLeft={false} />}
</Row>
)}
</StatItemColumn>
<StatItem title={<Trans>TVL</Trans>} value={poolData.tvlUSD} delta={poolData.tvlUSDChange} />
<StatItem title={<Trans>24H volume</Trans>} value={poolData.volumeUSD} delta={poolData.volumeUSDChange} />
<StatItem title={<Trans>24H fees</Trans>} value={poolData.volumeUSD * (poolData.feeTier / 1000000)} />
</StatsWrapper>
)
}
const StatsTextContainer = styled(Row)`
gap: 4px;
width: 100%;
align-items: flex-end;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
flex-direction: column;
gap: 0px;
align-items: flex-start;
}
`
const StatItemText = styled(Text)`
color: ${({ theme }) => theme.neutral1};
font-size: 36px;
font-weight: 485;
line-height: 44px;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
font-size: 20px;
line-height: 28px;
}
`
function StatItem({ title, value, delta }: { title: ReactNode; value: number; delta?: number }) {
const { formatNumber } = useFormatter()
return (
<StatItemColumn>
<ThemedText.BodySecondary>{title}</ThemedText.BodySecondary>
<StatsTextContainer>
<StatItemText>
{formatNumber({
input: value,
type: NumberType.FiatTokenStats,
})}
</StatItemText>
{!!delta && (
<Row width="max-content" padding="4px 0px">
<DeltaArrow delta={delta} />
<ThemedText.BodySecondary>{formatDelta(delta)}</ThemedText.BodySecondary>
</Row>
)}
</StatsTextContainer>
</StatItemColumn>
)
}

@ -0,0 +1,751 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PoolDetailsStats pool balance chart not visible on mobile 1`] = `
<DocumentFragment>
.c5 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c14 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
padding: 4px 0px;
}
.c6 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c15 {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 4px 0px;
}
.c4 {
color: #7D7D7D;
}
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c11 {
opacity: 0;
-webkit-transition: opacity 250ms ease-in;
transition: opacity 250ms ease-in;
width: 20px;
height: 20px;
border-radius: 50%;
}
.c10 {
width: 20px;
height: 20px;
background: #22222212;
-webkit-transition: background-color 250ms ease-in;
transition: background-color 250ms ease-in;
box-shadow: 0 0 1px white;
border-radius: 50%;
}
.c9 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.c16 {
color: #FF5F52;
}
.c2 {
font-weight: 485;
font-size: 24px;
line-height: 36px;
}
.c1 {
gap: 24px;
padding: 20px;
border-radius: 20px;
background: #F9F9F9;
width: 100%;
}
.c3 {
gap: 8px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
min-width: 180px;
}
.c7 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.c8 {
font-weight: 485;
font-size: 18px;
line-height: 24px;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
}
.c12 {
gap: 4px;
width: 100%;
-webkit-align-items: flex-end;
-webkit-box-align: flex-end;
-ms-flex-align: flex-end;
align-items: flex-end;
}
.c13 {
color: #222222;
font-size: 36px;
font-weight: 485;
line-height: 44px;
}
@media (max-width:1023px) {
.c2 {
width: 100%;
}
}
@media (max-width:1023px) {
.c1 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
background: #FFFFFF;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 20px 0px;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
}
@media (max-width:640px) {
.c3 {
min-width: 150px;
}
}
@media (max-width:1023px) {
.c7 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
}
@media (max-width:1023px) {
.c8 {
font-size: 20px;
line-height: 28px;
width: 100%;
}
}
@media (max-width:1023px) {
.c12 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0px;
-webkit-align-items: flex-start;
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
}
}
@media (max-width:1023px) {
.c13 {
font-size: 20px;
line-height: 28px;
}
}
<div
class="c0 c1"
>
<div
class="c2 css-vurnku"
>
Stats
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
Pool balances
</div>
<div
class="c5 c6 c7"
>
<div
class="c5 c6 c8"
>
<div
class="c9"
style="height: 20px; width: 20px; margin-right: 8px;"
>
<div
class="c10"
>
<img
alt="UNKNOWN logo"
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
</div>
</div>
90.93M USDC
</div>
<div
class="c5 c6 c8"
>
<div
class="c9"
style="height: 20px; width: 20px; margin-right: 8px;"
>
<div
class="c10"
>
<img
alt="WETH logo"
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"
/>
</div>
</div>
82,526.49 WETH
</div>
</div>
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
TVL
</div>
<div
class="c5 c6 c12"
>
<div
class="c13 css-vurnku"
>
$223.2M
</div>
<div
class="c14 c15"
width="max-content"
>
<svg
aria-label="down"
class="c16"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c4 css-1urox24"
>
0.37%
</div>
</div>
</div>
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
24H volume
</div>
<div
class="c5 c6 c12"
>
<div
class="c13 css-vurnku"
>
$233.4M
</div>
<div
class="c14 c15"
width="max-content"
>
<svg
aria-label="down"
class="c16"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c4 css-1urox24"
>
17.75%
</div>
</div>
</div>
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
24H fees
</div>
<div
class="c5 c6 c12"
>
<div
class="c13 css-vurnku"
>
$116.7K
</div>
</div>
</div>
</div>
</DocumentFragment>
`;
exports[`PoolDetailsStats renders stats text correctly 1`] = `
<DocumentFragment>
.c5 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c13 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
padding: 4px 0px;
}
.c6 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c14 {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 4px 0px;
}
.c4 {
color: #7D7D7D;
}
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c15 {
color: #FF5F52;
}
.c2 {
font-weight: 485;
font-size: 24px;
line-height: 36px;
}
.c1 {
gap: 24px;
padding: 20px;
border-radius: 20px;
background: #F9F9F9;
width: 100%;
}
.c3 {
gap: 8px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
min-width: 180px;
}
.c7 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.c8 {
font-weight: 485;
font-size: 18px;
line-height: 24px;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
}
.c9 {
height: 8px;
width: 40.698463777008904%;
background: #2172E5;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-right: 1px solid #F9F9F9;
}
.c10 {
height: 8px;
width: 59.3015362229911%;
background: #2172E5;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
border-left: 1px solid #F9F9F9;
}
.c11 {
gap: 4px;
width: 100%;
-webkit-align-items: flex-end;
-webkit-box-align: flex-end;
-ms-flex-align: flex-end;
align-items: flex-end;
}
.c12 {
color: #222222;
font-size: 36px;
font-weight: 485;
line-height: 44px;
}
@media (max-width:1023px) {
.c2 {
width: 100%;
}
}
@media (max-width:1023px) {
.c1 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
background: #FFFFFF;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 20px 0px;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
}
@media (max-width:640px) {
.c3 {
min-width: 150px;
}
}
@media (max-width:1023px) {
.c7 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
}
@media (max-width:1023px) {
.c8 {
font-size: 20px;
line-height: 28px;
width: 100%;
}
}
@media (max-width:1023px) {
.c11 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0px;
-webkit-align-items: flex-start;
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
}
}
@media (max-width:1023px) {
.c12 {
font-size: 20px;
line-height: 28px;
}
}
<div
class="c0 c1"
>
<div
class="c2 css-vurnku"
>
Stats
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
Pool balances
</div>
<div
class="c5 c6 c7"
>
<div
class="c5 c6 c8"
>
90.93M USDC
</div>
<div
class="c5 c6 c8"
>
82,526.49 WETH
</div>
</div>
<div
class="c5 c6"
data-testid="pool-balance-chart"
>
<div
class="c9"
/>
<div
class="c10"
/>
</div>
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
TVL
</div>
<div
class="c5 c6 c11"
>
<div
class="c12 css-vurnku"
>
$223.2M
</div>
<div
class="c13 c14"
width="max-content"
>
<svg
aria-label="down"
class="c15"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c4 css-1urox24"
>
0.37%
</div>
</div>
</div>
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
24H volume
</div>
<div
class="c5 c6 c11"
>
<div
class="c12 css-vurnku"
>
$233.4M
</div>
<div
class="c13 c14"
width="max-content"
>
<svg
aria-label="down"
class="c15"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c4 css-1urox24"
>
17.75%
</div>
</div>
</div>
</div>
<div
class="c0 c3"
>
<div
class="c4 css-1urox24"
>
24H fees
</div>
<div
class="c5 c6 c11"
>
<div
class="c12 css-vurnku"
>
$116.7K
</div>
</div>
</div>
</div>
</DocumentFragment>
`;

@ -17,6 +17,16 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
width: max-content; width: max-content;
} }
.c26 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
padding: 4px 0px;
}
.c1 { .c1 {
width: 100%; width: 100%;
display: -webkit-box; display: -webkit-box;
@ -72,6 +82,26 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
gap: 8px; gap: 8px;
} }
.c27 {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 4px 0px;
}
.c6 { .c6 {
color: #7D7D7D; color: #7D7D7D;
} }
@ -177,11 +207,185 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
border-radius: 50%; border-radius: 50%;
} }
.c2 { .c28 {
padding: 40px 56px; color: #FF5F52;
}
.c18 {
font-weight: 485;
font-size: 24px;
line-height: 36px;
}
.c17 {
gap: 24px;
padding: 20px;
border-radius: 20px;
background: #F9F9F9;
width: 100%; width: 100%;
} }
.c19 {
gap: 8px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
min-width: 180px;
}
.c20 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.c21 {
font-weight: 485;
font-size: 18px;
line-height: 24px;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
}
.c22 {
height: 8px;
width: 40.698463777008904%;
background: #2172E5;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-right: 1px solid #F9F9F9;
}
.c23 {
height: 8px;
width: 59.3015362229911%;
background: #2172E5;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
border-left: 1px solid #F9F9F9;
}
.c24 {
gap: 4px;
width: 100%;
-webkit-align-items: flex-end;
-webkit-box-align: flex-end;
-ms-flex-align: flex-end;
align-items: flex-end;
}
.c25 {
color: #222222;
font-size: 36px;
font-weight: 485;
line-height: 44px;
}
.c2 {
padding: 48px;
width: 100%;
-webkit-align-items: flex-start;
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
}
.c16 {
gap: 24px;
margin: 0 48px 0 auto;
width: 22vw;
min-width: 360px;
}
@media (max-width:1023px) {
.c18 {
width: 100%;
}
}
@media (max-width:1023px) {
.c17 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
background: #FFFFFF;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 20px 0px;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
}
@media (max-width:640px) {
.c19 {
min-width: 150px;
}
}
@media (max-width:1023px) {
.c20 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
}
@media (max-width:1023px) {
.c21 {
font-size: 20px;
line-height: 28px;
width: 100%;
}
}
@media (max-width:1023px) {
.c24 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0px;
-webkit-align-items: flex-start;
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
}
}
@media (max-width:1023px) {
.c25 {
font-size: 20px;
line-height: 28px;
}
}
@media (max-width:1023px) {
.c2 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
}
@media (max-width:639px) {
.c2 {
padding: 48px 16px;
}
}
@media (max-width:1023px) {
.c16 {
margin: 44px 0px;
width: 100%;
min-width: unset;
}
}
<div <div
class="c0 c1 c2" class="c0 c1 c2"
> >
@ -277,6 +481,155 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</svg> </svg>
</div> </div>
</div> </div>
<div
class="c3 c16"
>
<div
class="c3 c17"
>
<div
class="c18 css-vurnku"
>
Stats
</div>
<div
class="c3 c19"
>
<div
class="c6 css-1urox24"
>
Pool balances
</div>
<div
class="c0 c1 c20"
>
<div
class="c0 c1 c21"
>
90.93M USDC
</div>
<div
class="c0 c1 c21"
>
82,526.49 WETH
</div>
</div>
<div
class="c0 c1"
data-testid="pool-balance-chart"
>
<div
class="c22"
/>
<div
class="c23"
/>
</div>
</div>
<div
class="c3 c19"
>
<div
class="c6 css-1urox24"
>
TVL
</div>
<div
class="c0 c1 c24"
>
<div
class="c25 css-vurnku"
>
$223.2M
</div>
<div
class="c26 c27"
width="max-content"
>
<svg
aria-label="down"
class="c28"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c6 css-1urox24"
>
0.37%
</div>
</div>
</div>
</div>
<div
class="c3 c19"
>
<div
class="c6 css-1urox24"
>
24H volume
</div>
<div
class="c0 c1 c24"
>
<div
class="c25 css-vurnku"
>
$233.4M
</div>
<div
class="c26 c27"
width="max-content"
>
<svg
aria-label="down"
class="c28"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c6 css-1urox24"
>
17.75%
</div>
</div>
</div>
</div>
<div
class="c3 c19"
>
<div
class="c6 css-1urox24"
>
24H fees
</div>
<div
class="c0 c1 c24"
>
<div
class="c25 css-vurnku"
>
$116.7K
</div>
</div>
</div>
</div>
</div>
</div> </div>
</DocumentFragment> </DocumentFragment>
`; `;

@ -1,3 +1,4 @@
import Column from 'components/Column'
import Row from 'components/Row' import Row from 'components/Row'
import { getValidUrlChainName, supportedChainIdFromGQLChain } from 'graphql/data/util' import { getValidUrlChainName, supportedChainIdFromGQLChain } from 'graphql/data/util'
import { usePoolData } from 'graphql/thegraph/PoolData' import { usePoolData } from 'graphql/thegraph/PoolData'
@ -5,13 +6,37 @@ import NotFound from 'pages/NotFound'
import { useReducer } from 'react' import { useReducer } from 'react'
import { useParams } from 'react-router-dom' import { useParams } from 'react-router-dom'
import styled from 'styled-components' import styled from 'styled-components'
import { BREAKPOINTS } from 'theme'
import { isAddress } from 'utils' import { isAddress } from 'utils'
import { PoolDetailsHeader } from './PoolDetailsHeader' import { PoolDetailsHeader } from './PoolDetailsHeader'
import { PoolDetailsStats } from './PoolDetailsStats'
const PageWrapper = styled(Row)` const PageWrapper = styled(Row)`
padding: 40px 56px; padding: 48px;
width: 100%; width: 100%;
align-items: flex-start;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
flex-direction: column;
}
@media (max-width: ${BREAKPOINTS.sm - 1}px) {
padding: 48px 16px;
}
`
const RightColumn = styled(Column)`
gap: 24px;
margin: 0 48px 0 auto;
width: 22vw;
min-width: 360px;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
margin: 44px 0px;
width: 100%;
min-width: unset;
}
` `
export default function PoolDetailsPage() { export default function PoolDetailsPage() {
@ -41,6 +66,9 @@ export default function PoolDetailsPage() {
feeTier={poolData?.feeTier} feeTier={poolData?.feeTier}
toggleReversed={toggleReversed} toggleReversed={toggleReversed}
/> />
<RightColumn>
{poolData && <PoolDetailsStats poolData={poolData} isReversed={isReversed} chainId={chainId} />}
</RightColumn>
</PageWrapper> </PageWrapper>
) )
} }