Skip to content

Commit

Permalink
feat: modify pool token list layout
Browse files Browse the repository at this point in the history
  • Loading branch information
fairlighteth committed Oct 21, 2024
1 parent 8e64078 commit 6dd20c1
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ReactNode, useState } from 'react'

import { useTokensBalances } from '@cowprotocol/balances-and-allowances'
import { TokenListCategory, useAllLpTokens, useTokensByAddressMap } from '@cowprotocol/tokens'
import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'

import { TabButton, TabsContainer } from './styled'

Expand All @@ -12,9 +13,24 @@ interface LpTokenListsProps {
}

const tabs = [
{ title: 'All', value: null },
{ title: 'Pool tokens', value: [TokenListCategory.LP, TokenListCategory.COW_AMM_LP] },
{ title: 'CoW AMM only', value: [TokenListCategory.COW_AMM_LP] },
{ id: 'all', title: 'All', value: null },
{ id: 'pool', title: 'Pool tokens', value: [TokenListCategory.LP, TokenListCategory.COW_AMM_LP] },
{
id: 'cow-amm',
title: (
<>
<ProductLogo
variant={ProductVariant.CowAmm}
height={12}
overrideColor={UI.COLOR_TEXT_OPACITY_60}
theme="dark"
logoIconOnly
/>{' '}
CoW AMM only
</>
),
value: [TokenListCategory.COW_AMM_LP],
},
]

export function LpTokenListsWidget({ children }: LpTokenListsProps) {
Expand All @@ -26,20 +42,21 @@ export function LpTokenListsWidget({ children }: LpTokenListsProps) {
return (
<>
<TabsContainer>
{tabs.map((tab) => {
return (
<TabButton
key={tab.title}
active$={tab.value === listsCategories}
onClick={() => setListsCategories(tab.value)}
>
{tab.title}
</TabButton>
)
})}
{tabs.map((tab) => (
<TabButton key={tab.id} active$={tab.value === listsCategories} onClick={() => setListsCategories(tab.value)}>
{tab.title}
</TabButton>
))}
</TabsContainer>
{listsCategories === null ? (
children
) : lpTokens.length === 0 ? (
<LpTokenLists
displayCreatePoolBanner={listsCategories === tabs[2].value}
balancesState={balancesState}
tokensByAddress={tokensByAddress}
lpTokens={[]}
/>
) : (
<LpTokenLists
displayCreatePoolBanner={listsCategories === tabs[2].value}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
import { UI } from '@cowprotocol/ui'
import { Media, UI } from '@cowprotocol/ui'

import styled from 'styled-components/macro'

export const TabsContainer = styled.div`
display: flex;
flex-direction: row;
gap: 12px;
margin: 0 20px 15px 20px;
gap: 10px;
margin: 0 20px 20px;
${Media.upToSmall()} {
gap: 4px;
}
`
export const TabButton = styled.button<{ active$: boolean }>`
export const TabButton = styled.button<{ active$: boolean; isCowAmm?: boolean }>`
cursor: pointer;
border: 1px solid var(${UI.COLOR_BACKGROUND});
outline: none;
padding: 8px 16px;
border-radius: 32px;
font-size: 13px;
font-weight: 600;
color: var(${UI.COLOR_TEXT});
background: ${({ active$ }) => active$ ? `var(${UI.COLOR_BACKGROUND})` : 'transparent'};
font-size: 14px;
font-weight: ${({ active$ }) => (active$ ? '600' : '500')};
color: ${({ active$ }) => (active$ ? `var(${UI.COLOR_TEXT})` : `var(${UI.COLOR_TEXT_OPACITY_70})`)};
background: ${({ active$ }) => (active$ ? `var(${UI.COLOR_BACKGROUND})` : 'transparent')};
display: flex;
align-items: center;
gap: 4px;
${Media.upToSmall()} {
padding: 8px 12px;
font-size: 13px;
}
&:hover {
background : var(${UI.COLOR_BACKGROUND});
background: var(${UI.COLOR_BACKGROUND});
}
`
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { useCallback } from 'react'

import { BalancesState } from '@cowprotocol/balances-and-allowances'
import { LpToken } from '@cowprotocol/common-const'
import { useMediaQuery } from '@cowprotocol/common-hooks'
import { TokenLogo, TokensByAddress } from '@cowprotocol/tokens'
import { InfoTooltip, LoadingRows, LoadingRowSmall, TokenAmount, TokenName, TokenSymbol } from '@cowprotocol/ui'
import { Media } from '@cowprotocol/ui'
import { CurrencyAmount } from '@uniswap/sdk-core'

import { VirtualItem } from '@tanstack/react-virtual'
Expand All @@ -18,8 +20,16 @@ import {
LpTokenInfo,
LpTokenLogo,
LpTokenWrapper,
LpTokenYieldPercentage,
LpTokenBalance,
LpTokenTooltip,
NoPoolWrapper,
Wrapper,
EmptyList,
MobileCard,
MobileCardRow,
MobileCardLabel,
MobileCardValue,
} from './styled'

const LoadingElement = (
Expand All @@ -28,6 +38,36 @@ const LoadingElement = (
</LoadingRows>
)

const MobileCardRowItem: React.FC<{ label: string; value: React.ReactNode }> = ({ label, value }) => (
<MobileCardRow>
<MobileCardLabel>{label}:</MobileCardLabel>
<MobileCardValue>{value}</MobileCardValue>
</MobileCardRow>
)

const TokenInfo: React.FC<{ token: LpToken }> = ({ token }) => (
<>
<strong>
<TokenSymbol token={token} />
</strong>
<p>
<TokenName token={token} />
</p>
</>
)

const LpTokenLogos: React.FC<{ token0: string; token1: string; tokensByAddress: TokensByAddress; size: number }> = ({
token0,
token1,
tokensByAddress,
size,
}) => (
<LpTokenLogo>
<TokenLogo token={tokensByAddress[token0]} sizeMobile={size} />
<TokenLogo token={tokensByAddress[token1]} sizeMobile={size} />
</LpTokenLogo>
)

interface LpTokenListsProps {
lpTokens: LpToken[]
tokensByAddress: TokensByAddress
Expand All @@ -37,6 +77,7 @@ interface LpTokenListsProps {

export function LpTokenLists({ lpTokens, tokensByAddress, balancesState, displayCreatePoolBanner }: LpTokenListsProps) {
const { values: balances } = balancesState
const isMobile = useMediaQuery(Media.upToSmall(false))

const getItemView = useCallback(
(lpTokens: LpToken[], item: VirtualItem) => {
Expand All @@ -46,46 +87,69 @@ export function LpTokenLists({ lpTokens, tokensByAddress, balancesState, display
const balance = balances ? balances[token.address.toLowerCase()] : undefined
const balanceAmount = balance ? CurrencyAmount.fromRawAmount(token, balance.toHexString()) : undefined

const commonContent = (
<>
<LpTokenLogos token0={token0} token1={token1} tokensByAddress={tokensByAddress} size={isMobile ? 24 : 32} />
<LpTokenInfo>
<TokenInfo token={token} />
</LpTokenInfo>
</>
)

if (isMobile) {
return (
<MobileCard key={token.address}>
<MobileCardRow>{commonContent}</MobileCardRow>
<MobileCardRowItem
label="Balance"
value={balanceAmount ? <TokenAmount amount={balanceAmount} /> : LoadingElement}
/>
<MobileCardRowItem label="APR" value="40%" />
<MobileCardRowItem
label="Details"
value={
<LpTokenTooltip>
<InfoTooltip preText="Pool details" size={18}>
TODO
</InfoTooltip>
</LpTokenTooltip>
}
/>
</MobileCard>
)
}

return (
<ListItem data-address={token.address}>
<LpTokenWrapper>
<LpTokenLogo>
<div>
<TokenLogo token={tokensByAddress[token0]} sizeMobile={32} />
</div>
<div>
<TokenLogo token={tokensByAddress[token1]} sizeMobile={32} />
</div>
</LpTokenLogo>
<LpTokenInfo>
<strong>
<TokenSymbol token={token} />
</strong>
<p>
<TokenName token={token} />
</p>
</LpTokenInfo>
</LpTokenWrapper>
<span>{balanceAmount ? <TokenAmount amount={balanceAmount} /> : LoadingElement}</span>
<span>40%</span>
<span>
<InfoTooltip>TODO</InfoTooltip>
</span>
<LpTokenWrapper>{commonContent}</LpTokenWrapper>
<LpTokenBalance>{balanceAmount ? <TokenAmount amount={balanceAmount} /> : LoadingElement}</LpTokenBalance>
<LpTokenYieldPercentage>40%</LpTokenYieldPercentage>
<LpTokenTooltip>
<InfoTooltip size={18}>TODO</InfoTooltip>
</LpTokenTooltip>
</ListItem>
)
},
[balances, tokensByAddress],
[balances, tokensByAddress, isMobile],
)

return (
<Wrapper>
<ListHeader>
<span>Pool</span>
<span>Balance</span>
<span>APR</span>
<span></span>
</ListHeader>
<VirtualList items={lpTokens} getItemView={getItemView} />
{lpTokens.length > 0 ? (
<>
{!isMobile && (
<ListHeader>
<span>Pool</span>
<span>Balance</span>
<span>APR</span>
<span></span>
</ListHeader>
)}
<VirtualList items={lpTokens} getItemView={getItemView} />
</>
) : (
<EmptyList>No pool tokens available</EmptyList>
)}
{displayCreatePoolBanner && (
<NoPoolWrapper>
<div>Can’t find the pool you’re looking for?</div>
Expand Down
Loading

0 comments on commit 6dd20c1

Please sign in to comment.