Skip to content

Commit

Permalink
feat(EX-2694): earn improvement (#2584)
Browse files Browse the repository at this point in the history
* fix bug price format

* feat: add position history for position details page

* feat: add positions banner

* feat: add position status to position filters

* feat: add search to position filter

* feat: revamp user positions page UI

* feat: claim fees function in user positions page

* feat: add price range element for user positions page

* fix: fix responsive UI for price range

* fix: hide banner when no account connected

* chore: switch to pre-release API

* fix: fix claim disabled styles

* feat: add current price hover animation

* fix: fix data for 7d apr column

* feat: add logic detection for token-in, token-out in zap widget

* fix: fix logic default tokens in detection

* fix: positions banner

* chore: add error message for claim fees

* chore: remove console logs

* fix: token category api url

* fix: responsive for my positions screen

* feat: add workflow to post release note to Slack

* chore: prepare to release
  • Loading branch information
tienkane authored Feb 11, 2025
1 parent 79a68c9 commit a2b2e72
Show file tree
Hide file tree
Showing 23 changed files with 1,175 additions and 303 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/post-to-slack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: 'Post Release Notes to Slack'

on:
release:
types:
- released

jobs:
post_release_note:
uses: KyberNetwork/service-framework/.github/workflows/post-to-slack.yaml@main
with:
channel_id: C06EXALUR51
title: New _${{ github.event.repository.name }}_ release *${{ github.event.release.name }}*
body: ${{ github.event.release.body }}
secrets: inherit
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@kyberswap/ks-sdk-classic": "^1.0.3",
"@kyberswap/ks-sdk-core": "1.1.7",
"@kyberswap/ks-sdk-elastic": "^1.1.2",
"@kyberswap/liquidity-widgets": "1.1.10",
"@kyberswap/liquidity-widgets": "1.1.11",
"@kyberswap/zap-migration-widgets": "1.0.7",
"@kyberswap/oauth2": "1.0.2",
"@lingui/macro": "^4.6.0",
Expand Down
Binary file added src/assets/banners/earn_background_large.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/banners/earn_background_small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/banners/positions_background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/earn_background_large.png
Binary file not shown.
Binary file removed src/assets/images/earn_background_small.png
Binary file not shown.
5 changes: 5 additions & 0 deletions src/assets/svg/ic_claim.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions src/assets/svg/ic_position_current_price.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions src/components/EarnBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { Flex, Text } from 'rebass'
import { useExplorerLandingQuery } from 'services/zapEarn'
import styled, { css, keyframes } from 'styled-components'

import earnLargeBg from 'assets/images/earn_background_large.png'
import earnSmallBg from 'assets/images/earn_background_small.png'
import earnLargeBg from 'assets/banners/earn_background_large.png'
import earnSmallBg from 'assets/banners/earn_background_small.png'
import { APP_PATHS } from 'constants/index'
import { useActiveWeb3React } from 'hooks'
import useMixpanel, { MIXPANEL_TYPE } from 'hooks/useMixpanel'
Expand Down Expand Up @@ -43,10 +43,10 @@ const EarnBannerWrapper = styled.div`
align-items: center;
justify-content: space-between;
gap: 0.75rem;
padding: 22px 18px 22px 68px;
padding: 22px 18px 22px 70px;
background-image: url(${earnLargeBg});
background-position: center;
background-position: left;
background-size: cover;
${({ theme }) => theme.mediaWidth.upToXL`
Expand Down
9 changes: 6 additions & 3 deletions src/pages/Earns/PoolExplorer/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import styled from 'styled-components'
import { ReactComponent as DropdownSVG } from 'assets/svg/down.svg'
import { MEDIA_WIDTHS } from 'theme'

const DropdownWrapper = styled.div<{ mobileFullWidth: boolean }>`
const DropdownWrapper = styled.div<{ mobileFullWidth: boolean; mobileHalfWidth: boolean }>`
position: relative;
width: fit-content;
${({ theme, mobileFullWidth }) => theme.mediaWidth.upToSmall`
${({ theme, mobileFullWidth, mobileHalfWidth }) => theme.mediaWidth.upToSmall`
${mobileFullWidth && 'width: 100%;'}
${mobileHalfWidth && 'width: calc(50% - 4px);'}
`}
`

Expand Down Expand Up @@ -97,13 +98,15 @@ const DropdownMenu = ({
width,
alignLeft = false,
mobileFullWidth = false,
mobileHalfWidth = false,
onChange,
}: {
options: MenuOption[]
value: string | number
width?: number
alignLeft?: boolean
mobileFullWidth?: boolean
mobileHalfWidth?: boolean
onChange: (value: string | number) => void
}) => {
const upToExtraSmall = useMedia(`(max-width: ${MEDIA_WIDTHS.upToExtraSmall}px)`)
Expand Down Expand Up @@ -133,7 +136,7 @@ const DropdownMenu = ({
}, [ref])

return (
<DropdownWrapper mobileFullWidth={mobileFullWidth} ref={ref}>
<DropdownWrapper mobileFullWidth={mobileFullWidth} mobileHalfWidth={mobileHalfWidth} ref={ref}>
<DropdownTitleWrapper onClick={handleOpenChange}>
<DropdownTitle width={width}>
{optionValue?.icon && <ItemIcon src={optionValue.icon} alt={optionValue.label} />}
Expand Down
27 changes: 23 additions & 4 deletions src/pages/Earns/PositionDetail/ClaimFeeModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useMedia } from 'react-use'
import { Flex, Text } from 'rebass'

import ethereumIcon from 'assets/networks/ethereum.svg'
import { NotificationType } from 'components/Announcement/type'
import { ButtonOutlined, ButtonPrimary } from 'components/Button'
import Loader from 'components/Loader'
import Modal from 'components/Modal'
Expand All @@ -15,16 +16,29 @@ import { useWeb3React } from 'hooks'
import { useSigningContract } from 'hooks/useContract'
import useTheme from 'hooks/useTheme'
import { useChangeNetwork } from 'hooks/web3/useChangeNetwork'
import { useNotify } from 'state/application/hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
import { TRANSACTION_TYPE } from 'state/transactions/type'
import { MEDIA_WIDTHS } from 'theme'
import { formatDisplayNumber } from 'utils/numbers'

import { ParsedPosition } from '..'
import { NFT_MANAGER_CONTRACT } from '../../constants'
import { FeeInfo } from '../LeftSection'
import { ClaimInfo, ClaimInfoRow, ClaimInfoWrapper, ModalHeader, Wrapper, X } from './styles'

export interface PositionToClaim {
id: string
dex: string
chainId: number
token0Address: string
token1Address: string
token0Symbol: string
token1Symbol: string
token0Logo: string
token1Logo: string
chainLogo: string
}

export const isNativeToken = (tokenAddress: string, chainId: keyof typeof WETH) =>
tokenAddress.toLowerCase() === ETHER_ADDRESS.toLowerCase() ||
(WETH[chainId] && tokenAddress.toLowerCase() === WETH[chainId].address)
Expand All @@ -40,14 +54,15 @@ export default function ClaimFeeModal({
claiming: boolean
setClaiming: (claiming: boolean) => void
setClaimTx: (tx: string | null) => void
position: ParsedPosition
position: PositionToClaim
feeInfo: FeeInfo
onClose: () => void
}) {
const { library, account, chainId } = useWeb3React()
const theme = useTheme()
const upToExtraSmall = useMedia(`(max-width: ${MEDIA_WIDTHS.upToExtraSmall}px)`)
const addTransactionWithType = useTransactionAdder()
const notify = useNotify()
const { changeNetwork } = useChangeNetwork()

const [autoClaim, setAutoClaim] = useState(false)
Expand Down Expand Up @@ -131,9 +146,13 @@ export default function ClaimFeeModal({
},
})
setClaimTx(tx.hash)
onClose()
} catch (error) {
console.error(error)
notify({
title: t`Error`,
type: NotificationType.ERROR,
summary: error.message,
})
setClaiming(false)
}
}, [
Expand All @@ -150,7 +169,7 @@ export default function ClaimFeeModal({
isToken1Native,
library,
nftManagerContract,
onClose,
notify,
position.chainId,
position.id,
position.token0Address,
Expand Down
39 changes: 39 additions & 0 deletions src/pages/Earns/PositionDetail/LeftSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const LeftSection = ({ position }: { position: ParsedPosition }) => {
if (tx?.[0].receipt && tx?.[0].receipt.status === 1) {
setClaiming(false)
setClaimTx(null)
setOpenClaimFeeModal(false)
handleFetchUnclaimedFee()
}
}
Expand Down Expand Up @@ -272,6 +273,44 @@ const LeftSection = ({ position }: { position: ParsedPosition }) => {
</PositionAction>
</Flex>
</InfoSection>
{/* <InfoSection>
<Flex alignItems={'center'} justifyContent={'space-between'} marginBottom={2}>
<Text fontSize={14} color={theme.subText}>
{t`Created Time`}
</Text>
<Text>2:12:34 12/12/2024</Text>
</Flex>
<Flex alignItems={'center'} justifyContent={'space-between'} marginBottom={2}>
<Text fontSize={14} color={theme.subText}>
{t`Liquidity Source`}
</Text>
<Flex alignItems={'center'} sx={{ gap: '6px' }}>
<Text fontSize={14} color={theme.subText}>{t`Value`}</Text>
<Text>$12,600</Text>
</Flex>
</Flex>
<Flex flexDirection={'column'} alignItems={'flex-end'} sx={{ gap: 2 }} marginBottom={2}>
<Flex alignItems={'center'} sx={{ gap: '6px' }}>
<Text>345 KNC</Text> <Text>+ 12.65 JUP</Text> <Text>+ 0.18 ETH</Text>
</Flex>
<Flex alignItems={'center'} sx={{ gap: '6px' }}>
<Text fontSize={14} color={theme.subText}>{t`Tnx Hash`}</Text>
<Text color={theme.blue2}>
{shortenAddress(position.chainId as ChainId, '0xbf6ef625de5df898cc1d0f91868aae03976a2e2d', 4)}
</Text>
</Flex>
</Flex>
<Flex alignItems={'flex-start'} justifyContent={'space-between'}>
<Text fontSize={14} color={theme.subText}>{t`Past Actions`}</Text>
<Flex flexDirection={'column'} alignItems={'flex-end'} sx={{ gap: '6px' }}>
<Text>{t`Increased Liquidity`}</Text>
<Flex alignItems={'center'} sx={{ gap: '6px' }}>
<Text fontSize={14} color={theme.subText}>{t`Value`}</Text>
<Text>$12,600</Text>
</Flex>
</Flex>
</Flex>
</InfoSection> */}
</InfoLeftColumn>
)
}
Expand Down
49 changes: 37 additions & 12 deletions src/pages/Earns/UserPositions/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { t } from '@lingui/macro'
import { useEffect, useState } from 'react'
import { useMedia } from 'react-use'
import { Flex } from 'rebass'
import { PositionStatus } from 'services/zapEarn'

import { ReactComponent as RocketIcon } from 'assets/svg/rocket.svg'
import { APP_PATHS } from 'constants/index'
import Search from 'components/Search'
import useDebounce from 'hooks/useDebounce'
import { MEDIA_WIDTHS } from 'theme'

import DropdownMenu, { MenuOption } from '../PoolExplorer/DropdownMenu'
import { NavigateButton } from '../PoolExplorer/styles'
import { AllChainsOption, AllProtocolsOption } from '../useSupportedDexesAndChains'

const POSITION_STATUS = [
{ label: 'All Positions', value: '' },
{ label: 'In Range', value: PositionStatus.IN_RANGE },
{ label: 'Out Range', value: PositionStatus.OUT_RANGE },
]

export default function Filter({
supportedChains,
supportedDexes,
Expand All @@ -22,39 +29,57 @@ export default function Filter({
addresses: string
chainIds: string
protocols: string
status: string
q: string
}
onFilterChange: (key: string, value: string | number) => void
}) {
const [search, setSearch] = useState('')
const deboundedSearch = useDebounce(search, 300)
const upToSmall = useMedia(`(max-width: ${MEDIA_WIDTHS.upToSmall}px)`)

useEffect(() => {
if (filters.q !== deboundedSearch) {
onFilterChange('q', deboundedSearch || '')
}
}, [deboundedSearch, filters.q, onFilterChange])

return (
<Flex
flexDirection={upToSmall ? 'column-reverse' : 'row'}
flexDirection={upToSmall ? 'column' : 'row'}
alignItems={'center'}
justifyContent={'space-between'}
sx={{ gap: 2 }}
>
<Flex sx={{ gap: 2, width: upToSmall ? '100%' : 'auto' }}>
<Flex sx={{ gap: 2, width: upToSmall ? '100%' : 'auto' }} flexWrap={'wrap'}>
<DropdownMenu
alignLeft
mobileFullWidth
mobileHalfWidth
value={filters.chainIds}
options={supportedChains.length ? supportedChains : [AllChainsOption]}
onChange={value => value !== filters.chainIds && onFilterChange('chainIds', value)}
/>
<DropdownMenu
alignLeft
mobileFullWidth
mobileHalfWidth
value={filters.protocols}
options={supportedDexes.length ? supportedDexes : [AllProtocolsOption]}
onChange={value => value !== filters.protocols && onFilterChange('protocols', value)}
/>
<DropdownMenu
alignLeft
mobileFullWidth
value={filters.status}
options={POSITION_STATUS}
onChange={value => value !== filters.status && onFilterChange('status', value)}
/>
</Flex>
<NavigateButton
mobileFullWidth
icon={<RocketIcon width={20} height={20} />}
text={t`Explore Pools`}
to={APP_PATHS.EARN_POOLS}
<Search
placeholder={t`Search by token symbol or address`}
searchValue={search}
allowClear
onSearch={val => setSearch(val)}
style={{ height: '36px' }}
/>
</Flex>
)
Expand Down
Loading

0 comments on commit a2b2e72

Please sign in to comment.