diff --git a/components/shared/Change.tsx b/components/shared/Change.tsx index 3a266d37..7259468f 100644 --- a/components/shared/Change.tsx +++ b/components/shared/Change.tsx @@ -40,7 +40,7 @@ const Change = ({ ? 'text-th-up' : change < 0 ? 'text-th-down' - : 'text-th-fgd-4' + : 'text-th-fgd-2' }`} > {prefix ? prefix : ''} diff --git a/components/stats/SpotMarketsTable.tsx b/components/stats/SpotMarketsTable.tsx index dc1aeac7..b0d910cb 100644 --- a/components/stats/SpotMarketsTable.tsx +++ b/components/stats/SpotMarketsTable.tsx @@ -1,23 +1,49 @@ import { useTranslation } from 'next-i18next' -import { useMemo } from 'react' +import { useCallback } from 'react' import { useViewport } from '../../hooks/useViewport' import { COLORS } from '../../styles/colors' import { breakpoints } from '../../utils/theme' import ContentBox from '../shared/ContentBox' import MarketLogos from '@components/trade/MarketLogos' import useMangoGroup from 'hooks/useMangoGroup' -import { Table, Td, Th, TrBody, TrHead } from '@components/shared/TableElements' +import { + SortableColumnHeader, + Table, + Td, + Th, + TrBody, + TrHead, +} from '@components/shared/TableElements' import FormatNumericValue from '@components/shared/FormatNumericValue' import { floorToDecimal, getDecimalCount, numberCompacter } from 'utils/numbers' import SimpleAreaChart from '@components/shared/SimpleAreaChart' import { Disclosure, Transition } from '@headlessui/react' import { ChevronDownIcon } from '@heroicons/react/20/solid' -import MarketChange from '@components/shared/MarketChange' import useThemeWrapper from 'hooks/useThemeWrapper' import useListedMarketsWithMarketData, { SerumMarketWithMarketData, } from 'hooks/useListedMarketsWithMarketData' import { sortSpotMarkets } from 'utils/markets' +import { useSortableData } from 'hooks/useSortableData' +import Change from '@components/shared/Change' +import { Bank } from '@blockworks-foundation/mango-v4' + +type TableData = { + baseBank: Bank | undefined + change: number + market: SerumMarketWithMarketData + marketName: string + price: number + priceHistory: + | { + price: number + time: string + }[] + | undefined + quoteBank: Bank | undefined + volume: number + isUp: boolean +} const SpotMarketsTable = () => { const { t } = useTranslation('common') @@ -28,6 +54,64 @@ const SpotMarketsTable = () => { const { serumMarketsWithData, isLoading, isFetching } = useListedMarketsWithMarketData() + const formatedTableData = useCallback( + (markets: SerumMarketWithMarketData[]) => { + const formatted = [] + for (const m of markets) { + const baseBank = group?.getFirstBankByTokenIndex(m.baseTokenIndex) + const quoteBank = group?.getFirstBankByTokenIndex(m.quoteTokenIndex) + const market = group?.getSerum3ExternalMarket(m.serumMarketExternal) + let price = 0 + if (baseBank && market && quoteBank) { + price = floorToDecimal( + baseBank.uiPrice / quoteBank.uiPrice, + getDecimalCount(market.tickSize), + ).toNumber() + } + + const pastPrice = m?.marketData?.price_24h || 0 + + const priceHistory = m?.marketData?.price_history + + const volume = m?.marketData?.quote_volume_24h || 0 + + const change = volume > 0 ? ((price - pastPrice) / pastPrice) * 100 : 0 + + const marketName = m.name + + const isUp = + price && priceHistory && priceHistory.length + ? price >= priceHistory[0].price + : false + + const data = { + baseBank, + change, + market: m, + marketName, + price, + priceHistory, + quoteBank, + volume, + isUp, + } + formatted.push(data) + } + return formatted + }, + [group], + ) + + const { + items: tableData, + requestSort, + sortConfig, + } = useSortableData( + formatedTableData( + sortSpotMarkets(serumMarketsWithData, 'quote_volume_24h'), + ), + ) + const loadingMarketData = isLoading || isFetching return ( @@ -36,142 +120,152 @@ const SpotMarketsTable = () => {
{t('market')} | -{t('price')} | -{t('rolling-change')} | +
+ |
+
+
+
+ |
+
+
+
+ |
- | {t('trade:24h-volume')} | +
+
+
+ |
-
-
- {mkt.name} - |
-
-
-
-
- {price ? (
- <>
- |
-
-
-
- |
-
- {!loadingMarketData ? (
- priceHistory && priceHistory.length ? (
-
-
- ) : baseBank?.name === 'USDC' ||
- baseBank?.name === 'USDT' ? null : (
- - {t('unavailable')} - - ) - ) : ( - - )} - |
-
-
-
+
- {volume ? (
-
- {numberCompacter.format(volume)}{' '}
+ return (
+ {marketName}
+ {price ? (
+ <>
+ {t('unavailable')}
+ {volume ? (
+
+ {numberCompacter.format(volume)}{' '}
+
+ {quoteBank?.name}
- ) : (
-
- 0{' '}
-
- {quoteBank?.name}
-
+
+ ) : (
+
+ 0{' '}
+
+ {quoteBank?.name}
- )}
- |
+
---|
{market.name}
+{marketName}