From 4a722a1cfe6644b91318ec0889eaa20f407e1cef 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) => (
),