Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Pool list updates for v3 #79

Merged
merged 5 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
{
"mode": "auto"
}
]
],
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
91 changes: 80 additions & 11 deletions packages/lib/modules/pool/PoolList/PoolListFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
} from '@chakra-ui/react'
import { PoolListSearch } from './PoolListSearch'
import { getProjectConfig } from '@repo/lib/config/getProjectConfig'
import { usePoolListQueryState } from './usePoolListQueryState'
import { PROTOCOL_VERSION_TABS, usePoolListQueryState } from './usePoolListQueryState'
import {
PoolFilterType,
poolTypeFilters,
Expand All @@ -49,11 +49,14 @@ import { useDebouncedCallback } from 'use-debounce'
import { defaultDebounceMs } from '@repo/lib/shared/utils/queries'
import { motion, AnimatePresence } from 'framer-motion'
import { staggeredFadeInUp } from '@repo/lib/shared/utils/animations'
import { getChainShortName } from '@repo/lib/config/app.config'
import { getChainShortName, isDev, isStaging } from '@repo/lib/config/app.config'
import { usePoolList } from './PoolListProvider'
import { MultiSelect } from '@repo/lib/shared/components/inputs/MultiSelect'
import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql'
import { GqlChain, GqlPoolType } from '@repo/lib/shared/services/api/generated/graphql'
import Image from 'next/image'
import ButtonGroup, {
ButtonGroupOption,
} from '@repo/lib/shared/components/btns/button-group/ButtonGroup'

const SLIDER_MAX_VALUE = 10000000
const SLIDER_STEP_SIZE = 100000
Expand Down Expand Up @@ -133,9 +136,11 @@ function PoolTypeFilters() {
}
}, [poolTypes])

const _poolTypeFilters = poolTypeFilters.filter(poolType => poolType !== GqlPoolType.CowAmm)

return (
<Box animate="show" as={motion.div} exit="exit" initial="hidden" variants={staggeredFadeInUp}>
{poolTypeFilters.map(poolType => (
{_poolTypeFilters.map(poolType => (
<Box as={motion.div} key={poolType} variants={staggeredFadeInUp}>
<Checkbox
isChecked={!!poolTypes.find(selected => selected === poolType)}
Expand Down Expand Up @@ -380,12 +385,71 @@ const FilterButton = forwardRef<ButtonProps, 'button'>((props, ref) => {
)
})

function ProtocolVersionFilter() {
const {
togglePoolType,
setProtocolVersion,
protocolVersion,
poolTypes,
activeProtocolVersionTab,
setActiveProtocolVersionTab,
} = usePoolListQueryState()

const tabs =
isDev || isStaging
? PROTOCOL_VERSION_TABS
: PROTOCOL_VERSION_TABS.filter(tab => tab.value !== 'v3')

function toggleTab(option: ButtonGroupOption) {
setActiveProtocolVersionTab(option)
}

useEffect(() => {
if (protocolVersion === 3) {
setActiveProtocolVersionTab(tabs[2])
} else if (protocolVersion === 2) {
setActiveProtocolVersionTab(tabs[1])
} else if (poolTypes.includes(GqlPoolType.CowAmm)) {
setActiveProtocolVersionTab(tabs[3])
} else {
setActiveProtocolVersionTab(tabs[0])
}
}, [])

useEffect(() => {
if (activeProtocolVersionTab.value === 'cow') {
togglePoolType(true, GqlPoolType.CowAmm)
garethfuller marked this conversation as resolved.
Show resolved Hide resolved
} else if (activeProtocolVersionTab.value === 'v3') {
setProtocolVersion(3)
} else if (activeProtocolVersionTab.value === 'v2') {
setProtocolVersion(2)
} else {
setProtocolVersion(null)
}
}, [activeProtocolVersionTab])

return (
<ButtonGroup
currentOption={activeProtocolVersionTab}
options={tabs}
onChange={toggleTab}
size="xxs"
groupId="protocol-version"
/>
)
}

export function PoolListFilters() {
const { isConnected } = useUserAccount()
const [isPopoverOpen, setIsPopoverOpen] = useState(false)
const { resetFilters, totalFilterCount } = usePoolListQueryState()
const { resetFilters, totalFilterCount, setActiveProtocolVersionTab } = usePoolListQueryState()
const { isFixedPoolType } = usePoolList()

function _resetFilters() {
resetFilters()
setActiveProtocolVersionTab(PROTOCOL_VERSION_TABS[0])
}

return (
<VStack w="full">
<HStack gap="0" justify="end" spacing="none" w="full">
Expand All @@ -412,7 +476,7 @@ export function PoolListFilters() {
as={motion.div}
exit="exit"
initial="hidden"
spacing="xxs"
spacing="md"
variants={staggeredFadeInUp}
>
<Box as={motion.div} lineHeight="0" p="0" variants={staggeredFadeInUp}>
Expand All @@ -422,13 +486,12 @@ export function PoolListFilters() {
backgroundClip="text"
display="inline"
fontSize="xs"
lineHeight="1"
variant="eyebrow"
>
Filters
</Text>

<Button onClick={resetFilters} size="xs" variant="link">
<Button onClick={_resetFilters} size="xs" variant="link">
{totalFilterCount === 0 ? (
<VisuallyHidden>Reset all</VisuallyHidden>
) : (
Expand All @@ -447,21 +510,27 @@ export function PoolListFilters() {
</Box>
) : null}
<Box as={motion.div} variants={staggeredFadeInUp} w="full">
<Heading as="h3" my="sm" size="sm">
<Heading as="h3" mb="sm" size="sm">
Networks
</Heading>
<PoolNetworkFilters />
</Box>
<Box as={motion.div} variants={staggeredFadeInUp}>
<Heading as="h3" mb="sm" size="sm">
Protocol version
</Heading>
<ProtocolVersionFilter />
</Box>
{!isFixedPoolType && (
<Box as={motion.div} variants={staggeredFadeInUp}>
<Heading as="h3" my="sm" size="sm">
<Heading as="h3" mb="sm" size="sm">
Pool types
</Heading>
<PoolTypeFilters />
</Box>
)}
<Box as={motion.div} variants={staggeredFadeInUp}>
<Heading as="h3" my="sm" size="sm">
<Heading as="h3" mb="sm" size="sm">
Pool categories
</Heading>
<PoolCategoryFilters />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function PoolListTableHeader({ ...rest }) {
</GridItem>
<GridItem justifySelf="start">
<Text fontWeight="bold" textAlign="left">
Type
Details
</Text>
</GridItem>
{orderBy.map((orderByItem, index) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Grid, GridItem, GridProps, Text } from '@chakra-ui/react'
import { Box, Center, Grid, GridItem, GridProps, HStack, Text } from '@chakra-ui/react'
import Link from 'next/link'
import { getPoolPath, getPoolTypeLabel } from '../../pool.utils'
import MainAprTooltip from '@repo/lib/shared/components/tooltips/apr-tooltip/MainAprTooltip'
Expand All @@ -10,6 +10,9 @@ import { PoolListItem } from '../../pool.types'
import { PoolListTokenPills } from '../PoolListTokenPills'
import { getUserTotalBalanceUsd } from '../../user-balance.helpers'
import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView'
import { isCowAmmPool } from '../../pool.helpers'
import { BalBadge } from '@repo/lib/shared/components/badges/BalBadge'
import { CowIcon } from '@repo/lib/shared/components/icons/logos/CowIcon'

interface Props extends GridProps {
pool: PoolListItem
Expand All @@ -18,6 +21,35 @@ interface Props extends GridProps {

const MemoizedMainAprTooltip = memo(MainAprTooltip)

function PoolVersionTag({ pool }: { pool: PoolListItem }) {
if (isCowAmmPool(pool.type)) {
return (
<BalBadge w={8} h={8} p={0} fontSize="xs" color="font.secondary" textTransform="lowercase">
<Center w="full" h="full">
<CowIcon width={18} height={18} />
</Center>
</BalBadge>
)
} else if (pool.protocolVersion === 3) {
return (
<BalBadge w={8} h={8} p={0} fontSize="xs" color="font.secondary" textTransform="lowercase">
<Center w="full" h="full">
v3
</Center>
</BalBadge>
)
} else if (pool.protocolVersion === 2) {
return (
<BalBadge w={8} h={8} p={0} fontSize="xs" color="font.secondary" textTransform="lowercase">
<Center w="full" h="full">
v2
</Center>
</BalBadge>
)
}
return null
}

export function PoolListTableRow({ pool, keyValue, ...rest }: Props) {
const { userAddress } = usePoolListQueryState()
const { toCurrency } = useCurrency()
Expand Down Expand Up @@ -48,10 +80,13 @@ export function PoolListTableRow({ pool, keyValue, ...rest }: Props) {
iconSize={20}
/>
</GridItem>
<GridItem>
<Text textAlign="left" fontWeight="medium" textTransform="capitalize">
{getPoolTypeLabel(pool.type)}
</Text>
<GridItem minW="32">
<HStack>
<PoolVersionTag pool={pool} />
<Text textAlign="left" fontWeight="medium" textTransform="capitalize">
{getPoolTypeLabel(pool.type)}
</Text>
</HStack>
</GridItem>
{userAddress && (
<GridItem>
Expand Down
37 changes: 36 additions & 1 deletion packages/lib/modules/pool/PoolList/usePoolListQueryState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,45 @@ import {
SortingState,
} from '../pool.types'
import { PaginationState } from '@repo/lib/shared/components/pagination/pagination.types'
import { useState } from 'react'
import { ButtonGroupOption } from '@repo/lib/shared/components/btns/button-group/ButtonGroup'

export const PROTOCOL_VERSION_TABS: ButtonGroupOption[] = [
{
value: 'all',
label: 'All',
},
{
value: 'v2',
label: 'v2',
},
{
value: 'v3',
label: 'v3',
},
{
value: 'cow',
label: 'CoW',
},
] as const

export function usePoolListQueryState() {
const [first, setFirst] = useQueryState('first', poolListQueryStateParsers.first)
const [skip, setSkip] = useQueryState('skip', poolListQueryStateParsers.skip)
const [orderBy, setOrderBy] = useQueryState('orderBy', poolListQueryStateParsers.orderBy)

const [activeProtocolVersionTab, setActiveProtocolVersionTab] = useState(PROTOCOL_VERSION_TABS[0])

const [orderDirection, setOrderDirection] = useQueryState(
'orderDirection',
poolListQueryStateParsers.orderDirection
)

const [poolTypes, setPoolTypes] = useQueryState('poolTypes', poolListQueryStateParsers.poolTypes)
const [protocolVersion, setProtocolVersion] = useQueryState(
'protocolVersion',
poolListQueryStateParsers.protocolVersion
)
const [networks, setNetworks] = useQueryState('networks', poolListQueryStateParsers.networks)

const [textSearch, setTextSearch] = useQueryState(
Expand Down Expand Up @@ -150,14 +177,16 @@ export function usePoolListQueryState() {
setSkip(null)
setOrderBy(null)
setOrderDirection(null)
setProtocolVersion(null)
}

const totalFilterCount =
networks.length +
poolTypes.length +
(userAddress ? 1 : 0) +
(minTvl > 0 ? 1 : 0) +
poolCategories.length
poolCategories.length +
(protocolVersion ? 1 : 0)

const sorting: SortingState = orderBy
? [{ id: orderBy, desc: orderDirection === GqlPoolOrderDirection.Desc }]
Expand Down Expand Up @@ -192,6 +221,7 @@ export function usePoolListQueryState() {
minTvl,
tagIn: mappedPoolCategories.length > 0 ? mappedPoolCategories : null,
tagNotIn: ['BLACK_LISTED'],
protocolVersionIn: protocolVersion ? [protocolVersion] : undefined,
},
textSearch,
}
Expand All @@ -205,6 +235,7 @@ export function usePoolListQueryState() {
poolTypes,
networks,
textSearch,
protocolVersion,
},
toggleUserAddress,
toggleNetwork,
Expand All @@ -220,7 +251,11 @@ export function usePoolListQueryState() {
resetFilters,
poolCategoryLabel,
setNetworks,
setProtocolVersion,
setActiveProtocolVersionTab,
activeProtocolVersionTab,
poolCategories,
protocolVersion,
minTvl,
searchText: textSearch,
pagination,
Expand Down
1 change: 1 addition & 0 deletions packages/lib/modules/pool/pool.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const poolListQueryStateParsers = {
parseAsStringEnum<PoolFilterType>(Object.values(poolTypeFilters))
).withDefault([]),
networks: parseAsArrayOf(parseAsStringEnum<GqlChain>(Object.values(GqlChain))).withDefault([]),
protocolVersion: parseAsInteger,
textSearch: parseAsString,
userAddress: parseAsString,
minTvl: parseAsFloat.withDefault(0),
Expand Down
21 changes: 21 additions & 0 deletions packages/lib/shared/components/badges/BalBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Badge, BadgeProps } from '@chakra-ui/react'

export function BalBadge({ children, ...props }: BadgeProps) {
return (
<Badge
fontWeight="normal"
py="xs"
px="sm"
background="background.level2"
border="1px solid"
borderColor="border.base"
shadow="sm"
rounded="full"
display="flex"
alignItems="center"
{...props}
>
{children}
</Badge>
)
}
10 changes: 8 additions & 2 deletions packages/lib/shared/components/icons/logos/CowIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* eslint-disable max-len */
export function CowIcon() {
export function CowIcon({ width = 36, height = 24 }: { width?: number; height?: number }) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="24" fill="none">
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 0 36 24"
fill="none"
>
<path
fill="currentColor"
fillRule="evenodd"
Expand Down
Loading