From b94e3a7ae259416880b8bd38b13ecb69aa87c5f4 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:06:17 +0200 Subject: [PATCH] feat: markets category route --- src/pages/Markets/Category.tsx | 47 +++++++++++++ src/pages/Markets/MarketsHeader.tsx | 45 +++++++++--- src/pages/Markets/MarketsPage.tsx | 3 +- src/pages/Markets/Recommended.tsx | 7 +- src/pages/Markets/components/MarketsRow.tsx | 76 +++++++++++++++++++++ src/pages/Markets/hooks/useRows.tsx | 22 +++--- 6 files changed, 176 insertions(+), 24 deletions(-) create mode 100644 src/pages/Markets/Category.tsx create mode 100644 src/pages/Markets/components/MarketsRow.tsx diff --git a/src/pages/Markets/Category.tsx b/src/pages/Markets/Category.tsx new file mode 100644 index 00000000000..3ec2b83d111 --- /dev/null +++ b/src/pages/Markets/Category.tsx @@ -0,0 +1,47 @@ +import { Box } from '@chakra-ui/react' +import { useMemo } from 'react' +import { useTranslate } from 'react-polyglot' +import { useParams } from 'react-router' +import { Main } from 'components/Layout/Main' +import { SEO } from 'components/Layout/Seo' + +import { MarketsRow } from './components/MarketsRow' +import type { MARKETS_CATEGORIES } from './constants' +import { useRows } from './hooks/useRows' +import { MarketsHeader } from './MarketsHeader' + +const containerPaddingX = { base: 4, xl: 0 } + +const ASSETS_LIMIT = 100 + +export const Category: React.FC = () => { + const params: { category: MARKETS_CATEGORIES } = useParams() + const translate = useTranslate() + const headerComponent = useMemo(() => , []) + + const allRows = useRows({ limit: ASSETS_LIMIT }) + const row = allRows[params.category] + + const body = useMemo( + () => ( + + {row.component} + + ), + [row.category, row.component, row.subtitle, row.supportedChainIds, row.title], + ) + + return ( +
+ + + {body} + +
+ ) +} diff --git a/src/pages/Markets/MarketsHeader.tsx b/src/pages/Markets/MarketsHeader.tsx index 183db6b7704..910e137c613 100644 --- a/src/pages/Markets/MarketsHeader.tsx +++ b/src/pages/Markets/MarketsHeader.tsx @@ -38,6 +38,21 @@ export const MarketsHeader = () => { history.push('/explore') }, [history]) + const maybeCategory = useMemo( + () => + history.location.pathname.match(/\/markets\/category\/(?[\w]+)/)?.groups?.category, + [history.location.pathname], + ) + const headingCopy = useMemo(() => { + if (maybeCategory) return `markets.categories.${maybeCategory}.title` + return 'navBar.markets' + }, [maybeCategory]) + + const subtitleCopy = useMemo(() => { + if (maybeCategory) return `markets.categories.${maybeCategory}.subtitle` + return 'markets.marketsBody' + }, [maybeCategory]) + return ( <> @@ -46,20 +61,30 @@ export const MarketsHeader = () => { - {translate('navBar.markets')} + {translate(headingCopy)} - - - - {translate('navBar.markets')} - - - - - + {!maybeCategory && ( + // Don't show tabs and heading when on a single category view + <> + + + + {translate(headingCopy)} + + + + + + + )} ) diff --git a/src/pages/Markets/MarketsPage.tsx b/src/pages/Markets/MarketsPage.tsx index bce4a3d0d0a..cf9a8cd4c52 100644 --- a/src/pages/Markets/MarketsPage.tsx +++ b/src/pages/Markets/MarketsPage.tsx @@ -1,5 +1,6 @@ import { Redirect, Route, Switch, useRouteMatch } from 'react-router' +import { Category } from './Category' import { Recommended } from './Recommended' export const MarketsPage = () => { @@ -14,7 +15,7 @@ export const MarketsPage = () => { - + diff --git a/src/pages/Markets/Recommended.tsx b/src/pages/Markets/Recommended.tsx index 4883f026ba5..08c3e9bb533 100644 --- a/src/pages/Markets/Recommended.tsx +++ b/src/pages/Markets/Recommended.tsx @@ -4,7 +4,7 @@ import { useTranslate } from 'react-polyglot' import { Main } from 'components/Layout/Main' import { SEO } from 'components/Layout/Seo' -import { LpRow } from './components/Row' +import { MarketsRow } from './components/MarketsRow' import { useRows } from './hooks/useRows' import { MarketsHeader } from './MarketsHeader' @@ -21,14 +21,15 @@ export const Recommended: React.FC = () => { const body = useMemo( () => Object.values(rows).map((row, i) => ( - {row.component} - + )), [rows], ) diff --git a/src/pages/Markets/components/MarketsRow.tsx b/src/pages/Markets/components/MarketsRow.tsx new file mode 100644 index 00000000000..22bf6d244c2 --- /dev/null +++ b/src/pages/Markets/components/MarketsRow.tsx @@ -0,0 +1,76 @@ +import { ArrowBackIcon } from '@chakra-ui/icons' +import { Box, Flex, Heading, IconButton, Text } from '@chakra-ui/react' +import type { ChainId } from '@shapeshiftoss/caip' +import { KnownChainIds } from '@shapeshiftoss/types' +import { useMemo, useState } from 'react' +import { Link, useHistory, useParams } from 'react-router-dom' +import { ChainDropdown } from 'components/ChainDropdown/ChainDropdown' +import { selectFeatureFlag } from 'state/slices/selectors' +import { useAppSelector } from 'state/store' + +import type { MARKETS_CATEGORIES } from '../constants' + +type RowProps = { + title: string + subtitle?: string + supportedChainIds: ChainId[] | undefined + category: MARKETS_CATEGORIES + children: (selectedChainId: ChainId | undefined) => React.ReactNode +} + +const backIcon = + +export const MarketsRow: React.FC = ({ + title, + subtitle, + supportedChainIds, + children, + category, +}) => { + const params: { category?: MARKETS_CATEGORIES } = useParams() + const history = useHistory() + const handleBack = history.goBack + const isCategoryRoute = params.category + const [selectedChainId, setSelectedChainId] = useState(undefined) + const isArbitrumNovaEnabled = useAppSelector(state => selectFeatureFlag(state, 'ArbitrumNova')) + + const chainIds = useMemo(() => { + if (!supportedChainIds) + return Object.values(KnownChainIds).filter(chainId => { + if (!isArbitrumNovaEnabled && chainId === KnownChainIds.ArbitrumNovaMainnet) return false + return true + }) + + return supportedChainIds + }, [isArbitrumNovaEnabled, supportedChainIds]) + + return ( + + + + + {isCategoryRoute && ( + + )} + + {title} + + + {subtitle && ( + + {subtitle} + + )} + + + + {children(selectedChainId)} + + ) +} diff --git a/src/pages/Markets/hooks/useRows.tsx b/src/pages/Markets/hooks/useRows.tsx index 47c220fd771..543b52ea2c6 100644 --- a/src/pages/Markets/hooks/useRows.tsx +++ b/src/pages/Markets/hooks/useRows.tsx @@ -45,8 +45,8 @@ export const useRows = ({ limit }: { limit: number }) => { () => ({ [MARKETS_CATEGORIES.TRADING_VOLUME]: { category: MARKETS_CATEGORIES.TRADING_VOLUME, - title: translate('markets.categories.tradingVolume.title'), - subtitle: translate('markets.categories.tradingVolume.subtitle'), + title: translate(`markets.categories.${MARKETS_CATEGORIES.TRADING_VOLUME}.title`), + subtitle: translate(`markets.categories.${MARKETS_CATEGORIES.TRADING_VOLUME}.subtitle`), component: (selectedChainId: ChainId | undefined) => ( { }, [MARKETS_CATEGORIES.MARKET_CAP]: { category: MARKETS_CATEGORIES.MARKET_CAP, - title: translate('markets.categories.marketCap.title'), - subtitle: translate('markets.categories.marketCap.subtitle'), + title: translate(`markets.categories.${MARKETS_CATEGORIES.MARKET_CAP}.title`), + subtitle: translate(`markets.categories.${MARKETS_CATEGORIES.MARKET_CAP}.subtitle`), component: (selectedChainId: ChainId | undefined) => ( { }, [MARKETS_CATEGORIES.TRENDING]: { category: MARKETS_CATEGORIES.TRENDING, - title: translate('markets.categories.trending.title'), - subtitle: translate('markets.categories.trending.subtitle', { percentage: '10' }), + title: translate(`markets.categories.${MARKETS_CATEGORIES.TRENDING}.title`), + subtitle: translate(`markets.categories.${MARKETS_CATEGORIES.TRENDING}.subtitle`, { + percentage: '10', + }), component: (selectedChainId: ChainId | undefined) => ( { }, [MARKETS_CATEGORIES.TOP_MOVERS]: { category: MARKETS_CATEGORIES.TOP_MOVERS, - title: translate('markets.categories.topMovers.title'), + title: translate(`markets.categories.${MARKETS_CATEGORIES.TOP_MOVERS}.title`), component: (selectedChainId: ChainId | undefined) => ( { }, [MARKETS_CATEGORIES.RECENTLY_ADDED]: { category: MARKETS_CATEGORIES.RECENTLY_ADDED, - title: translate('markets.categories.recentlyAdded.title'), + title: translate(`markets.categories.${MARKETS_CATEGORIES.RECENTLY_ADDED}.title`), // TODO(gomes): loading state when implemented component: (selectedChainId: ChainId | undefined) => ( { }, [MARKETS_CATEGORIES.ONE_CLICK_DEFI]: { category: MARKETS_CATEGORIES.ONE_CLICK_DEFI, - title: translate('markets.categories.oneClickDefiAssets.title'), + title: translate(`markets.categories.${MARKETS_CATEGORIES.ONE_CLICK_DEFI}.title`), component: (selectedChainId: ChainId | undefined) => ( ), @@ -117,7 +119,7 @@ export const useRows = ({ limit }: { limit: number }) => { }, [MARKETS_CATEGORIES.THORCHAIN_DEFI]: { category: MARKETS_CATEGORIES.THORCHAIN_DEFI, - title: translate('markets.categories.thorchainDefi.title'), + title: translate(`markets.categories.${MARKETS_CATEGORIES.THORCHAIN_DEFI}.title`), component: (selectedChainId: ChainId | undefined) => ( ),