From e71dd326eca4db0aada068aa3f7565ffc03dd6b6 Mon Sep 17 00:00:00 2001 From: Danh Date: Fri, 22 Sep 2023 15:50:18 +0700 Subject: [PATCH] connect api categories --- .../YieldPools/ElasticFarmGroup/index.tsx | 2 +- .../TrueSightV2/components/KyberAIWidget.tsx | 1 - .../TrueSightV2/components/TokenFilter.tsx | 185 +++++++------ .../TrueSightV2/components/table/index.tsx | 2 +- src/pages/TrueSightV2/constants/index.tsx | 3 +- .../TrueSightV2/hooks/useKyberAIData.tsx | 19 +- src/pages/TrueSightV2/pages/SingleToken.tsx | 53 ++-- .../TrueSightV2/pages/TokenAnalysisList.tsx | 248 ++++++++---------- src/services/baseQueryOauth.ts | 2 +- 9 files changed, 262 insertions(+), 253 deletions(-) diff --git a/src/components/YieldPools/ElasticFarmGroup/index.tsx b/src/components/YieldPools/ElasticFarmGroup/index.tsx index 0c2670fc19..9a746f4ea3 100644 --- a/src/components/YieldPools/ElasticFarmGroup/index.tsx +++ b/src/components/YieldPools/ElasticFarmGroup/index.tsx @@ -74,7 +74,7 @@ enum SORT_FIELD { MY_REWARD = 'my_reward', } -const ProMMFarmGroup: React.FC = ({ address, onOpenModal, pools, userInfo, onShowStepGuide, tokenPrices }) => { +const ElasticFarmGroup: React.FC = ({ address, onOpenModal, pools, onShowStepGuide, tokenPrices }) => { const theme = useTheme() const { account, chainId } = useActiveWeb3React() const above1000 = useMedia('(min-width: 1000px)') diff --git a/src/pages/TrueSightV2/components/KyberAIWidget.tsx b/src/pages/TrueSightV2/components/KyberAIWidget.tsx index 37e77c908b..dafe9f9a02 100644 --- a/src/pages/TrueSightV2/components/KyberAIWidget.tsx +++ b/src/pages/TrueSightV2/components/KyberAIWidget.tsx @@ -210,7 +210,6 @@ export default function Widget() { [WidgetTab.Bullish]: KyberAIListType.BULLISH, [WidgetTab.TrendingSoon]: KyberAIListType.TRENDING_SOON, }[activeTab], - chain: 'all', page: 1, pageSize: 5, }, diff --git a/src/pages/TrueSightV2/components/TokenFilter.tsx b/src/pages/TrueSightV2/components/TokenFilter.tsx index a93d013d66..5eda35dce8 100644 --- a/src/pages/TrueSightV2/components/TokenFilter.tsx +++ b/src/pages/TrueSightV2/components/TokenFilter.tsx @@ -1,51 +1,24 @@ import { ChainId } from '@kyberswap/ks-sdk-core' -import { ReactNode, useState } from 'react' +import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import Skeleton from 'react-loading-skeleton' import { useMedia } from 'react-use' import { Text } from 'rebass' import styled, { css } from 'styled-components' +import { FadeInAnimation } from 'components/Animation' import { ButtonGray } from 'components/Button' import Column from 'components/Column' import Icon from 'components/Icons/Icon' -import Select, { SelectOption } from 'components/Select' +import Select from 'components/Select' +import useShowLoadingAtLeastTime from 'hooks/useShowLoadingAtLeastTime' import useTheme from 'hooks/useTheme' import MultipleChainSelect from 'pages/MyEarnings/MultipleChainSelect' import SubscribeButtonKyberAI from 'pages/TrueSightV2/components/SubscireButtonKyberAI' -import { NETWORK_TO_CHAINID, Z_INDEX_KYBER_AI } from 'pages/TrueSightV2/constants' +import { NETWORK_TO_CHAINID, SUPPORTED_NETWORK_KYBERAI, Z_INDEX_KYBER_AI } from 'pages/TrueSightV2/constants' +import { useGetFilterCategoriesQuery } from 'pages/TrueSightV2/hooks/useKyberAIData' +import { useSessionInfo } from 'state/authen/hooks' import { MEDIA_WIDTHS } from 'theme' -const categories: { [key: string]: SelectOption[] } = { - categories: [ - { label: 'All Categories', value: '' }, - { label: 'Defi', value: 'defi' }, - { label: 'Gamefi', value: 'gamefi' }, - { label: 'Layer 2', value: 'layer2' }, - ], - market_cap: [ - { label: 'All Market Cap', value: '' }, - { label: 'Less than $1M', value: '0,1000000' }, - { label: 'More than $1M', value: '1000000' }, - { label: 'More than $10M', value: '10000000' }, - { label: 'More than $100M', value: '100000000' }, - { label: 'More than $500M', value: '500000000' }, - ], - holders: [ - { label: 'All Holders', value: '' }, - { label: 'Less than 1,000', value: '0,1000' }, - { label: 'More than 1,000', value: '1000' }, - { label: 'More than 10,000', value: '10000' }, - ], - market: [ - { label: 'All Markets', value: '' }, - { label: 'DEXes', value: 'dexes' }, - { label: 'CEXes', value: 'cexes' }, - ], - chain: [ - { label: 'All Chains', value: 'all' }, - { label: 'BNB Chain', value: 'bsc' }, - ], -} - const SELECT_SIZE = '60px' const shareStyle = css` @@ -59,6 +32,11 @@ const shareStyle = css` `} ` +const StyledSkeleton = styled(Skeleton)` + ${shareStyle} + width: 150px; +` + const StyledSelect = styled(Select)` ${shareStyle} ` @@ -121,32 +99,72 @@ const SelectGroup = styled.div` `} ` +const getChainsFromSlugs = (values: string[] | undefined) => + (values || []).map(item => NETWORK_TO_CHAINID[item || '']).filter(Boolean) + export default function TokenFilter({ handleFilterChange, - handleChainChange, setShowShare, + onTrackingSelectChain, + defaultFilter = {}, }: { handleFilterChange: (filter: Record) => void - handleChainChange: (v?: ChainId) => void setShowShare: (v: boolean) => void + onTrackingSelectChain: (v: string) => void + defaultFilter: { [k: string]: string } }) { + const [filter, setFilter] = useState(defaultFilter) + + const onChangeFilter = useCallback( + (key: string, value: string) => { + const newFilter = { ...filter, [key]: value } + setFilter(newFilter) + handleFilterChange(newFilter) + }, + [setFilter, handleFilterChange, filter], + ) + + const { isLogin } = useSessionInfo() + const { data = [], isFetching } = useGetFilterCategoriesQuery(undefined, { skip: !isLogin }) + const showLoading = useShowLoadingAtLeastTime(isFetching, 500) + + const { allChainIds, listSelects, chainFilter } = useMemo(() => { + const [chainFilter, ...listSelects] = data + const allChainIds = getChainsFromSlugs(chainFilter?.values.map(item => item.value + '')) + + return { allChainIds, listSelects, chainFilter } + }, [data]) + + const defaultChains = useMemo( + () => getChainsFromSlugs(defaultFilter[chainFilter?.queryKey]?.split(',')), + [defaultFilter, chainFilter], + ) + + // todo watch list chains + + const theme = useTheme() + const [selectedChains, setSelectChains] = useState([]) + const handleChainChange = useCallback( + (values: ChainId[]) => { + if (!chainFilter?.queryKey) return + setSelectChains(values) + const selectAllChain = values.length === allChainIds.length + const valueStr = selectAllChain ? '' : values.map(id => SUPPORTED_NETWORK_KYBERAI[id]).join(',') + onTrackingSelectChain(selectAllChain ? 'All' : valueStr) + onChangeFilter(chainFilter.queryKey, valueStr) + }, + [chainFilter, onChangeFilter, allChainIds, onTrackingSelectChain], + ) + + const isInit = useRef(false) + useEffect(() => { + if (isInit.current || defaultChains.length + allChainIds.length === 0) return + isInit.current = true + setSelectChains(defaultChains.length ? defaultChains : allChainIds) + }, [allChainIds, defaultChains]) + + // todo loading de len filter const upToSmall = useMedia(`(max-width: ${MEDIA_WIDTHS.upToSmall}px)`) - const [filter, setFilter] = useState({}) - - const onChangeFilter = (key: string, value: string) => { - const newFilter = { ...filter, [key]: value } - setFilter(newFilter) - handleFilterChange(newFilter) - } - - const listSelects = [ - { key: 'chain', label: 'Chains' }, - { key: 'market_cap', label: 'Market Cap' }, - { key: 'holders', label: 'Holders' }, - { key: 'categories', label: 'Categories' }, - { key: 'market', label: 'Markets' }, - // todo watch list - ] const activeRender = (name: string, label: ReactNode) => ( @@ -157,34 +175,45 @@ export default function TokenFilter({ ) - const theme = useTheme() - const [selectedChains, setSelectChains] = useState(Object.values(NETWORK_TO_CHAINID)) - return ( - activeRender('Chains', node)} - /> - {listSelects.map(({ key, label }) => ( - activeRender(label, item?.label)} - options={categories[key]} - onChange={value => onChangeFilter(key, value)} - optionStyle={{ fontSize: '14px' }} - menuStyle={{ zIndex: Z_INDEX_KYBER_AI.FILTER_TOKEN_OPTIONS, top: upToSmall ? undefined : SELECT_SIZE }} - /> - ))} + {showLoading ? ( + new Array(5) + .fill(0) + .map((_, i) => ) + ) : ( + <> + activeRender('Chains', node)} + /> + {listSelects.map(({ queryKey, displayName, values }) => ( + activeRender(displayName, item?.label)} + options={values} + onChange={value => onChangeFilter(queryKey, value)} + optionStyle={{ fontSize: '14px' }} + menuStyle={{ + zIndex: Z_INDEX_KYBER_AI.FILTER_TOKEN_OPTIONS, + top: upToSmall ? undefined : SELECT_SIZE, + maxHeight: 400, + overflowY: 'scroll', + }} + /> + ))} + + )} res.data, }), + // filter + getFilterCategories: builder.query<{ displayName: string; queryKey: string; values: SelectOption[] }[], void>({ + query: () => ({ + url: `https://truesight-v2.dev.kyberengineering.io/truesight/api/v2/assets/filters`, // todo + }), + transformResponse: (res: any) => + res.data.map((e: any) => ({ + ...e, + values: [ + { label: t`All ${e.displayName}`, value: '' }, + ...e.values.map((opt: any) => ({ label: opt.displayName, value: opt.queryValue })), + ], + })), + }), }), }) @@ -279,5 +295,6 @@ export const { useSearchTokenQuery, useLazySearchTokenQuery, useFundingRateQuery, + useGetFilterCategoriesQuery, } = kyberAIApi export default kyberAIApi diff --git a/src/pages/TrueSightV2/pages/SingleToken.tsx b/src/pages/TrueSightV2/pages/SingleToken.tsx index b5ce2c85fb..e194b5e945 100644 --- a/src/pages/TrueSightV2/pages/SingleToken.tsx +++ b/src/pages/TrueSightV2/pages/SingleToken.tsx @@ -15,9 +15,11 @@ import Icon from 'components/Icons/Icon' import { DotsLoader } from 'components/Loader/DotsLoader' import Row, { RowBetween, RowFit } from 'components/Row' import { APP_PATHS } from 'constants/index' +import { useActiveWeb3React } from 'hooks' import { MIXPANEL_TYPE, useMixpanelKyberAI } from 'hooks/useMixpanel' import useTheme from 'hooks/useTheme' import { PROFILE_MANAGE_ROUTES } from 'pages/NotificationCenter/const' +import { StarWithAnimation } from 'pages/TrueSightV2/components/WatchlistStar' import { MEDIA_WIDTHS } from 'theme' import DisplaySettings from '../components/DisplaySettings' @@ -26,7 +28,6 @@ import KyberAIShareModal from '../components/KyberAIShareModal' import SimpleTooltip from '../components/SimpleTooltip' import SwitchVariantDropdown from '../components/SwitchVariantDropdown' import { TokenOverview } from '../components/TokenOverview' -import WatchlistButton from '../components/WatchlistButton' import ExploreShareContent from '../components/shareContent/ExploreTopShareContent' import { MIXPANEL_KYBERAI_TAG, NETWORK_IMAGE_URL, NETWORK_TO_CHAINID } from '../constants' import useChartStatesReducer, { ChartStatesContext } from '../hooks/useChartStatesReducer' @@ -258,7 +259,7 @@ const TokenNameGroup = ({ token, isLoading }: { token?: IAssetOverview; isLoadin const { account } = useActiveWeb3React() const theme = useTheme() - // const mixpanelHandler = useMixpanelKyberAI() + const mixpanelHandler = useMixpanelKyberAI() const navigate = useNavigate() const location = useLocation() const above768 = useMedia(`(min-width:${MEDIA_WIDTHS.upToSmall}px)`) @@ -268,30 +269,30 @@ const TokenNameGroup = ({ token, isLoading }: { token?: IAssetOverview; isLoadin const [removeFromWatchlist, { isLoading: loadingRemovefromWatchlist }] = useRemoveFromWatchlistMutation() const [isWatched, setIsWatched] = useState(false) - // const handleStarClick = () => { - // if (!token || !chain || !account) return - // if (isWatched) { - // mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { - // token_name: token.symbol?.toUpperCase(), - // source: 'explore', - // option: 'remove', - // }) - - // removeFromWatchlist({ - // tokenAddress: token?.address, - // chain, - // }).then(() => setIsWatched(false)) - // } else { - // if (!reachedMaxLimit) { - // mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { - // token_name: token.symbol?.toUpperCase(), - // source: 'explore', - // option: 'add', - // }) - // addToWatchlist({ tokenAddress: token?.address, chain }).then(() => setIsWatched(true)) - // } - // } - // } + const handleStarClick = () => { + if (!token || !chain || !account) return + if (isWatched) { + mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { + token_name: token.symbol?.toUpperCase(), + source: 'explore', + option: 'remove', + }) + + removeFromWatchlist({ + tokenAddress: token?.address, + chain, + }).then(() => setIsWatched(false)) + } else { + if (!reachedMaxLimit) { + mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { + token_name: token.symbol?.toUpperCase(), + source: 'explore', + option: 'add', + }) + addToWatchlist({ tokenAddress: token?.address, chain }).then(() => setIsWatched(true)) + } + } + } const handleGoBackClick = () => { if (!!location?.state?.from) { navigate(location.state.from) diff --git a/src/pages/TrueSightV2/pages/TokenAnalysisList.tsx b/src/pages/TrueSightV2/pages/TokenAnalysisList.tsx index ac007b6196..2de2824eca 100644 --- a/src/pages/TrueSightV2/pages/TokenAnalysisList.tsx +++ b/src/pages/TrueSightV2/pages/TokenAnalysisList.tsx @@ -1,9 +1,8 @@ -import { ChainId } from '@kyberswap/ks-sdk-core' import { Trans, t } from '@lingui/macro' import dayjs from 'dayjs' import { motion } from 'framer-motion' import { rgba } from 'polished' -import { ReactNode, useEffect, useMemo, useRef, useState } from 'react' +import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { ArrowDown, ArrowUp } from 'react-feather' import Skeleton, { SkeletonTheme } from 'react-loading-skeleton' import { useLocation, useNavigate, useSearchParams } from 'react-router-dom' @@ -20,12 +19,14 @@ import Row, { RowFit } from 'components/Row' import TabButton from 'components/TabButton' import { TextDotted } from 'components/Tooltip' import { APP_PATHS, ICON_ID, SORT_DIRECTION } from 'constants/index' -import { NETWORKS_INFO } from 'constants/networks' +import { useActiveWeb3React } from 'hooks' import { MIXPANEL_TYPE, useMixpanelKyberAI } from 'hooks/useMixpanel' import { useOnClickOutside } from 'hooks/useOnClickOutside' import useTheme from 'hooks/useTheme' import { StyledSectionWrapper } from 'pages/TrueSightV2/components' import TokenFilter from 'pages/TrueSightV2/components/TokenFilter' +import { StarWithAnimation } from 'pages/TrueSightV2/components/WatchlistStar' +import useIsReachMaxLimitWatchedToken from 'pages/TrueSightV2/hooks/useIsReachMaxLimitWatchedToken' import { MEDIA_WIDTHS } from 'theme' import ChevronIcon from '../components/ChevronIcon' @@ -39,8 +40,8 @@ import TokenListVariants from '../components/TokenListVariants' import WatchlistButton from '../components/WatchlistButton' import KyberScoreChart from '../components/chart/KyberScoreChart' import TokenAnalysisListShareContent from '../components/shareContent/TokenAnalysisListShareContent' -import { KYBERAI_LISTYPE_TO_MIXPANEL, SUPPORTED_NETWORK_KYBERAI, Z_INDEX_KYBER_AI } from '../constants' -import { useTokenListQuery } from '../hooks/useKyberAIData' +import { KYBERAI_LISTYPE_TO_MIXPANEL, Z_INDEX_KYBER_AI } from '../constants' +import { useAddToWatchlistMutation, useRemoveFromWatchlistMutation, useTokenListQuery } from '../hooks/useKyberAIData' import { IKyberScoreChart, ITokenList, KyberAIListType, QueryTokenParams } from '../types' import { calculateValueToColor, formatLocaleStringNum, formatTokenPrice, navigateToSwapPage } from '../utils' @@ -461,90 +462,78 @@ const TokenRow = ({ const navigate = useNavigate() const location = useLocation() const mixpanelHandler = useMixpanelKyberAI() - // const { account } = useActiveWeb3React() + const { account } = useActiveWeb3React() const theme = useTheme() - const [showMenu, setShowMenu] = useState(false) + const reachedMaxLimit = useIsReachMaxLimitWatchedToken() + const [addToWatchlist] = useAddToWatchlistMutation() + const [removeFromWatchlist] = useRemoveFromWatchlistMutation() + const [showSwapMenu, setShowSwapMenu] = useState(false) - const [menuLeft, setMenuLeft] = useState(undefined) - // const [addToWatchlist] = useAddToWatchlistMutation() - // const [removeFromWatchlist] = useRemoveFromWatchlistMutation() - // const reachedMaxLimit = useIsReachMaxLimitWatchedToken(token?.tokens.length) - // const [isWatched, setIsWatched] = useState(false) - // const [loadingStar, setLoadingStar] = useState(false) + const [isWatched, setIsWatched] = useState(false) + const [loadingStar, setLoadingStar] = useState(false) const rowRef = useRef(null) const menuRef = useRef(null) - useOnClickOutside(menuRef, () => setShowMenu(false)) useOnClickOutside(menuRef, () => setShowSwapMenu(false)) const above768 = useMedia(`(min-width:${MEDIA_WIDTHS.upToSmall}px)`) const hasMutipleChain = token.tokens.length > 1 - const handleRowClick = (e: any) => { - if (hasMutipleChain) { - const left = e.clientX - (rowRef.current?.getBoundingClientRect()?.left || 0) - const rowWidth = rowRef.current?.getBoundingClientRect()?.width || 0 - const menuWidth = menuRef.current?.getBoundingClientRect()?.width || 0 - if (left !== undefined) { - setMenuLeft(Math.min(left, rowWidth - menuWidth)) - setShowMenu(true) - } - } else { - navigate(`${APP_PATHS.KYBERAI_EXPLORE}/${token.tokens[0].chain}/${token.tokens[0].address}`, { - state: { from: location }, + const handleRowClick = () => { + navigate(`${APP_PATHS.KYBERAI_EXPLORE}/${token.asset_id}`, { + state: { from: location }, + }) + } + + const handleWatchlistClick = (e: any) => { + e.stopPropagation() + if (!account) return + setLoadingStar(true) + if (isWatched) { + mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { + token_name: token.symbol?.toUpperCase(), + source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], + ranking_order: index, + option: 'remove', + }) + Promise.all(token.tokens.map(t => removeFromWatchlist({ tokenAddress: t.address, chain: t.chain }))).then(() => { + setIsWatched(false) + setLoadingStar(false) }) + } else { + if (!reachedMaxLimit) { + mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { + token_name: token.symbol?.toUpperCase(), + source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], + ranking_order: index, + option: 'add', + }) + Promise.all(token.tokens.map(t => addToWatchlist({ tokenAddress: t.address, chain: t.chain }))).then(() => { + setIsWatched(true) + setLoadingStar(false) + }) + } } } - // const handleWatchlistClick = (e: any) => { - // e.stopPropagation() - // if (!account) return - // setLoadingStar(true) - // if (isWatched) { - // mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { - // token_name: token.symbol?.toUpperCase(), - // source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], - // ranking_order: index, - // option: 'remove', - // }) - // Promise.all(token.tokens.map(t => removeFromWatchlist({ tokenAddress: t.address, chain: t.chain }))).then(() => { - // setIsWatched(false) - // setLoadingStar(false) - // }) - // } else { - // if (!reachedMaxLimit) { - // mixpanelHandler(MIXPANEL_TYPE.KYBERAI_ADD_TOKEN_TO_WATCHLIST, { - // token_name: token.symbol?.toUpperCase(), - // source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], - // ranking_order: index, - // option: 'add', - // }) - // Promise.all(token.tokens.map(t => addToWatchlist({ tokenAddress: t.address, chain: t.chain }))).then(() => { - // setIsWatched(true) - // setLoadingStar(false) - // }) - // } - // } - // } - - // useEffect(() => { - // setIsWatched(token.isWatched) - // }, [token.isWatched]) + useEffect(() => { + setIsWatched(token.isWatched) + }, [token.isWatched]) const latestKyberScore: IKyberScoreChart | undefined = token?.ks_3d?.[token.ks_3d.length - 1] return ( - + - {/* */} + {above768 ? index : <>} @@ -571,9 +560,7 @@ const TokenRow = ({ {token.symbol}{' '} - - - + @@ -644,14 +631,9 @@ const TokenRow = ({ source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], option: 'explore', }) - if (hasMutipleChain) { - setMenuLeft(undefined) - setShowMenu(true) - } else { - navigate(`${APP_PATHS.KYBERAI_EXPLORE}/${token.tokens[0].chain}/${token.tokens[0].address}`, { - state: { from: location }, - }) - } + navigate(`${APP_PATHS.KYBERAI_EXPLORE}/${token.asset_id}`, { + state: { from: location }, + }) }} > @@ -668,7 +650,6 @@ const TokenRow = ({ option: 'swap', }) if (hasMutipleChain) { - setMenuLeft(undefined) setShowSwapMenu(true) } else { navigateToSwapPage(token.tokens[0]) @@ -679,29 +660,15 @@ const TokenRow = ({ {hasMutipleChain && ( - <> - - navigate(`${APP_PATHS.KYBERAI_EXPLORE}/${chain}/${address}`, { - state: { from: location }, - }) + { + if (chain && address) { + navigateToSwapPage({ chain, address }) } - /> - { - if (chain && address) { - navigateToSwapPage({ chain, address }) - } - }} - /> - + }} + /> )} @@ -748,6 +715,16 @@ enum SORT_FIELD { FUNDING_RATe = 'fd', } +const formatParamsFromUrl = (searchParams: URLSearchParams) => { + const { page, listType, ...filter } = Object.fromEntries(searchParams) + return { + page: +page || 1, + listTypeParam: (listType as KyberAIListType) || KyberAIListType.BULLISH, + filter, + } +} +const pageSize = 25 + export default function TokenAnalysisList() { const theme = useTheme() const mixpanelHandler = useMixpanelKyberAI() @@ -760,25 +737,10 @@ export default function TokenAnalysisList() { const isMobile = useMedia(`(max-width:${SIZE_MOBILE})`) const [searchParams, setSearchParams] = useSearchParams() - // todo refactor - const pageSize = 25 - const { chain, page, listTypeParam, ...filter } = useMemo(() => { - const { page, chain, listType, ...filter } = Object.fromEntries(searchParams) - return { - page: +page || 1, - listTypeParam: (listType as KyberAIListType) || KyberAIListType.BULLISH, - chain: chain || 'all', - ...filter, - } - }, [searchParams]) + const { page, listTypeParam, filter } = useMemo(() => formatParamsFromUrl(searchParams), [searchParams]) const queryParams = useMemo(() => { - const params: QueryTokenParams = { - page, - pageSize, - chain: (chain && SUPPORTED_NETWORK_KYBERAI[Number(chain) as ChainId]) || 'all', - ...filter, - } + const params: QueryTokenParams = { page, pageSize, ...filter } if (listTypeParam === KyberAIListType.MYWATCHLIST) { params.watchlist = true params.type = KyberAIListType.ALL @@ -786,7 +748,7 @@ export default function TokenAnalysisList() { params.type = listTypeParam } return params - }, [chain, page, listTypeParam, filter]) + }, [page, listTypeParam, filter]) const { data, isLoading, isFetching, isError } = useTokenListQuery(queryParams) const listData = data?.data || [] @@ -796,31 +758,30 @@ export default function TokenAnalysisList() { searchParams.set('page', '1') setSearchParams(searchParams) } - const handleFilterChange = (filter: Record) => { - Object.entries(filter).forEach(([key, value]) => searchParams.set(key, value)) - setSearchParams(searchParams) - } + const handleFilterChange = useCallback( + (filter: Record) => { + Object.entries(filter).forEach(([key, value]) => { + value === '' || value === undefined ? searchParams.delete(key) : searchParams.set(key, value) + }) + searchParams.set('page', '1') + setSearchParams(searchParams) + }, + [searchParams, setSearchParams], + ) + const handlePageChange = (page: number) => { searchParams.set('page', page.toString()) setSearchParams(searchParams) } - const handleChainChange = (chainId?: ChainId) => { - if (!chainId) { - searchParams.delete('chain') - mixpanelHandler(MIXPANEL_TYPE.KYBERAI_RANKING_SWITCH_CHAIN_CLICK, { - source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], - network: 'All', - }) - } else { - searchParams.set('chain', chainId.toString()) + const onTrackingSelectChain = useCallback( + (network: string) => { mixpanelHandler(MIXPANEL_TYPE.KYBERAI_RANKING_SWITCH_CHAIN_CLICK, { source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], - network: NETWORKS_INFO[chainId].name, + network, }) - } - searchParams.set('page', '1') - setSearchParams(searchParams) - } + }, + [listType, mixpanelHandler], + ) useEffect(() => { if (wrapperRef.current && tableRef.current) { @@ -877,9 +838,10 @@ export default function TokenAnalysisList() { @@ -890,7 +852,7 @@ export default function TokenAnalysisList() { inset: '0 0 0 0', background: theme.background, opacity: 0.8, - zIndex: 100, + zIndex: Z_INDEX_KYBER_AI.LOADING_TOKENS_TABLE, borderRadius: isMobile ? 0 : '20px', display: 'flex', alignItems: 'center', @@ -1052,7 +1014,7 @@ export default function TokenAnalysisList() { listData.map((token: ITokenList, index: number) => ( mixpanelHandler(MIXPANEL_TYPE.KYBERAI_SHARE_TOKEN_CLICK, { token_name: 'share_list_token', - network: chain, + network: filter.chains || 'all', source: KYBERAI_LISTYPE_TO_MIXPANEL[listType], share_via: social, }) diff --git a/src/services/baseQueryOauth.ts b/src/services/baseQueryOauth.ts index 8b6c1fce8a..7952d9b344 100644 --- a/src/services/baseQueryOauth.ts +++ b/src/services/baseQueryOauth.ts @@ -10,7 +10,7 @@ const queryWithTokenAndTracking = async (config: any, baseUrl: string, withAcces // mapping rtk query vs axios config.data = config.data || config.body } - config.url = baseUrl + config.url + config.url = (config.url.startsWith('http') ? '' : baseUrl) + config.url const result = await (withAccessToken ? KyberOauth2Api.call(config) : axios(config)) return { data: result.data } } catch (err) {