From d63bdf18877e341ade7e56810165c88a181a353a Mon Sep 17 00:00:00 2001 From: Charles Bachmeier Date: Thu, 28 Sep 2023 09:27:29 -0700 Subject: [PATCH] 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 * 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 --- src/graphql/thegraph/PoolData.ts | 2 +- .../PoolDetails/PoolDetailsStats.test.tsx | 37 + src/pages/PoolDetails/PoolDetailsStats.tsx | 223 ++++++ .../PoolDetailsStats.test.tsx.snap | 751 ++++++++++++++++++ .../__snapshots__/index.test.tsx.snap | 357 ++++++++- src/pages/PoolDetails/index.tsx | 30 +- 6 files changed, 1396 insertions(+), 4 deletions(-) create mode 100644 src/pages/PoolDetails/PoolDetailsStats.test.tsx create mode 100644 src/pages/PoolDetails/PoolDetailsStats.tsx create mode 100644 src/pages/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap diff --git a/src/graphql/thegraph/PoolData.ts b/src/graphql/thegraph/PoolData.ts index d736d6e26c..d7d55fef22 100644 --- a/src/graphql/thegraph/PoolData.ts +++ b/src/graphql/thegraph/PoolData.ts @@ -51,7 +51,7 @@ gql` } ` -interface PoolData { +export interface PoolData { // basic token info address: string feeTier: number diff --git a/src/pages/PoolDetails/PoolDetailsStats.test.tsx b/src/pages/PoolDetails/PoolDetailsStats.test.tsx new file mode 100644 index 0000000000..e8b5e79850 --- /dev/null +++ b/src/pages/PoolDetails/PoolDetailsStats.test.tsx @@ -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() + 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() + expect(asFragment()).toMatchSnapshot() + + expect(screen.queryByTestId('pool-balance-chart')).toBeNull() + }) +}) diff --git a/src/pages/PoolDetails/PoolDetailsStats.tsx b/src/pages/PoolDetails/PoolDetailsStats.tsx new file mode 100644 index 0000000000..fd5d480f51 --- /dev/null +++ b/src/pages/PoolDetails/PoolDetailsStats.tsx @@ -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 ( + + + Stats + + + + Pool balances + + + + {!screenIsNotLarge && ( + + )} + {formatNumber({ + input: token0.tvl, + type: NumberType.TokenNonTx, + })} +   + {token0.symbol} + + + {!screenIsNotLarge && ( + + )} + {formatNumber({ + input: token1.tvl, + type: NumberType.TokenNonTx, + })} +   + {token1.symbol} + + + {screenIsNotLarge && ( + + {token0.color && } + {token1.color && } + + )} + + TVL} value={poolData.tvlUSD} delta={poolData.tvlUSDChange} /> + 24H volume} value={poolData.volumeUSD} delta={poolData.volumeUSDChange} /> + 24H fees} value={poolData.volumeUSD * (poolData.feeTier / 1000000)} /> + + ) +} + +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 ( + + {title} + + + {formatNumber({ + input: value, + type: NumberType.FiatTokenStats, + })} + + {!!delta && ( + + + {formatDelta(delta)} + + )} + + + ) +} diff --git a/src/pages/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap b/src/pages/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap new file mode 100644 index 0000000000..2bea8407e2 --- /dev/null +++ b/src/pages/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap @@ -0,0 +1,751 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PoolDetailsStats pool balance chart not visible on mobile 1`] = ` + + .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; + } +} + +
+
+ Stats +
+
+
+ Pool balances +
+
+
+
+
+ UNKNOWN logo +
+
+ 90.93M USDC +
+
+
+
+ WETH logo +
+
+ 82,526.49 WETH +
+
+
+
+
+ TVL +
+
+
+ $223.2M +
+
+ + + +
+ 0.37% +
+
+
+
+
+
+ 24H volume +
+
+
+ $233.4M +
+
+ + + +
+ 17.75% +
+
+
+
+
+
+ 24H fees +
+
+
+ $116.7K +
+
+
+
+
+`; + +exports[`PoolDetailsStats renders stats text correctly 1`] = ` + + .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; + } +} + +
+
+ Stats +
+
+
+ Pool balances +
+
+
+ 90.93M USDC +
+
+ 82,526.49 WETH +
+
+
+
+
+
+
+
+
+ TVL +
+
+
+ $223.2M +
+
+ + + +
+ 0.37% +
+
+
+
+
+
+ 24H volume +
+
+
+ $233.4M +
+
+ + + +
+ 17.75% +
+
+
+
+
+
+ 24H fees +
+
+
+ $116.7K +
+
+
+
+ +`; diff --git a/src/pages/PoolDetails/__snapshots__/index.test.tsx.snap b/src/pages/PoolDetails/__snapshots__/index.test.tsx.snap index e4b67ec655..84c96e5367 100644 --- a/src/pages/PoolDetails/__snapshots__/index.test.tsx.snap +++ b/src/pages/PoolDetails/__snapshots__/index.test.tsx.snap @@ -17,6 +17,16 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the 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 { width: 100%; display: -webkit-box; @@ -72,6 +82,26 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the 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 { color: #7D7D7D; } @@ -177,11 +207,185 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the border-radius: 50%; } -.c2 { - padding: 40px 56px; +.c28 { + color: #FF5F52; +} + +.c18 { + font-weight: 485; + font-size: 24px; + line-height: 36px; +} + +.c17 { + gap: 24px; + padding: 20px; + border-radius: 20px; + background: #F9F9F9; 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; + } +} +
@@ -277,6 +481,155 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
+
+
+
+ Stats +
+
+
+ Pool balances +
+
+
+ 90.93M USDC +
+
+ 82,526.49 WETH +
+
+
+
+
+
+
+
+
+ TVL +
+
+
+ $223.2M +
+
+ + + +
+ 0.37% +
+
+
+
+
+
+ 24H volume +
+
+
+ $233.4M +
+
+ + + +
+ 17.75% +
+
+
+
+
+
+ 24H fees +
+
+
+ $116.7K +
+
+
+
+
`; diff --git a/src/pages/PoolDetails/index.tsx b/src/pages/PoolDetails/index.tsx index d1d7ce4622..4c4cca6d02 100644 --- a/src/pages/PoolDetails/index.tsx +++ b/src/pages/PoolDetails/index.tsx @@ -1,3 +1,4 @@ +import Column from 'components/Column' import Row from 'components/Row' import { getValidUrlChainName, supportedChainIdFromGQLChain } from 'graphql/data/util' import { usePoolData } from 'graphql/thegraph/PoolData' @@ -5,13 +6,37 @@ import NotFound from 'pages/NotFound' import { useReducer } from 'react' import { useParams } from 'react-router-dom' import styled from 'styled-components' +import { BREAKPOINTS } from 'theme' import { isAddress } from 'utils' import { PoolDetailsHeader } from './PoolDetailsHeader' +import { PoolDetailsStats } from './PoolDetailsStats' const PageWrapper = styled(Row)` - padding: 40px 56px; + padding: 48px; 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() { @@ -41,6 +66,9 @@ export default function PoolDetailsPage() { feeTier={poolData?.feeTier} toggleReversed={toggleReversed} /> + + {poolData && } + ) }