Skip to content

Commit

Permalink
Adjust CRT marketplace tables
Browse files Browse the repository at this point in the history
  • Loading branch information
ikprk committed Jul 8, 2024
1 parent 5c785a8 commit 84a9f39
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 19 deletions.
184 changes: 184 additions & 0 deletions packages/atlas/src/components/HotCreatorTokens/HotCreatorTokens.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import styled from '@emotion/styled'
import BN from 'bn.js'
import { useMemo } from 'react'

import { useGetMostInteractedEntityByTypeQuery } from '@/api/queries/__generated__/admin.generated'
import { useGetHotAndColdTokensQuery } from '@/api/queries/__generated__/creatorTokens.generated'
import { SvgEmptyStateIllustration } from '@/assets/illustrations'
import { JoyTokenIcon } from '@/components/JoyTokenIcon'
import { NumberFormat } from '@/components/NumberFormat'
import { Section } from '@/components/Section/Section'
import { TableProps } from '@/components/Table'
import { RightAlignedHeader } from '@/components/Table/Table.styles'
import { Text } from '@/components/Text'
import { SkeletonLoader } from '@/components/_loaders/SkeletonLoader'
import { absoluteRoutes } from '@/config/routes'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { sendUserInteraction } from '@/utils/interactions'

import { PercentageChangeIndicator } from '../PercentageChangeIndicator'
import {
JoyAmountWrapper,
SkeletonChannelContainer,
StyledTable,
} from '../TopSellingChannelsTable/TopSellingChannelsTable.styles'
import { TokenInfo } from '../_crt/CrtPortfolioTable'

const getColumns = (interval: number): TableProps['columns'] => [
{
Header: '',
accessor: 'index',
width: 1,
},
{
Header: 'TOKEN',
accessor: 'token',
width: 5,
},
{
Header: () => <RightAlignedHeader>PRICE % {interval}D</RightAlignedHeader>,
accessor: 'priceChange',
width: 4,
},
{
Header: () => <RightAlignedHeader>PRICE</RightAlignedHeader>,
accessor: 'price',
width: 4,
},
]

const tableEmptyState = {
title: 'No tokens found',
description: 'No top moves have been found.',
icon: <SvgEmptyStateIllustration />,
}

export const HotCreatorTokens = ({ interval, tableTitle }: { interval: number; tableTitle: string }) => {
const { data: topInteractedTokens } = useGetMostInteractedEntityByTypeQuery({
variables: {
period: interval,
type: 'MarketplaceTokenEntry',
},
})
const { data, loading } = useGetHotAndColdTokensQuery({
variables: {
periodDays: interval,
limit: 10,
where: {
id_in: topInteractedTokens?.getTopInteractedEnities.map((entity) => entity.entityId),
},
},
})

const columns = getColumns(interval)
const { tokensWithPriceChange: _tokensWithPriceChange } = data ?? {}
const tokensWithPriceChange = _tokensWithPriceChange?.filter((token) => token.pricePercentageChange != 0)

const lgMatch = useMediaMatch('lg')
const mappedData = useMemo(() => {
return loading
? Array.from({ length: 10 }, () => ({
index: null,
token: (
<SkeletonChannelContainer>
<SkeletonLoader width={32} height={32} rounded />
<SkeletonLoader width="30%" height={26} />
</SkeletonChannelContainer>
),
weeklyPriceChange: (
<JoyAmountWrapper>
<SkeletonLoader width={120} height={26} />
</JoyAmountWrapper>
),
price: (
<JoyAmountWrapper>
<SkeletonLoader width={120} height={26} />
</JoyAmountWrapper>
),
channelId: null,
}))
: tokensWithPriceChange?.map((data, index) => ({
index: (
<IndexText variant="t100" as="p" color="colorTextMuted">
#{index + 1}{' '}
</IndexText>
),
price: (
<JoyAmountWrapper>
<NumberFormat
icon={<JoyTokenIcon variant="gray" />}
variant="t200-strong"
as="p"
value={new BN(data.creatorToken.lastPrice ?? 0)}
margin={{ left: 1 }}
format="short"
withDenomination
denominationAlign="right"
/>
</JoyAmountWrapper>
),
priceChange: (
<JoyAmountWrapper>
<PercentageChangeIndicator value={data.pricePercentageChange} />
</JoyAmountWrapper>
),
token: (
<TokenInfo
channelId={data.creatorToken.channel?.channel.id ?? ''}
tokenName={data.creatorToken.symbol ?? ''}
isVerified={false}
tokenTitle={data.creatorToken.symbol ?? ''}
/>
),
channelId: data.creatorToken.channel?.channel.id,
})) ?? []
}, [tokensWithPriceChange, loading])

if (!loading && !tokensWithPriceChange) {
return null
}

return (
<Section
headerProps={{
start: {
type: 'title',
title: tableTitle,
},
}}
contentProps={{
type: 'grid',
grid: {
sm: {
columns: 1,
},
},
children: [
<StyledTable
key="single"
minWidth={350}
emptyState={tableEmptyState}
columns={columns}
data={mappedData}
doubleColumn={lgMatch}
onRowClick={(idx) => {
if (tokensWithPriceChange?.[idx].creatorToken.id) {
sendUserInteraction('MarketplaceTokenEntry', tokensWithPriceChange[idx].creatorToken.id).catch(
() => undefined
)
}
}}
getRowTo={(idx) => {
return absoluteRoutes.viewer.channel(mappedData[idx].channelId ?? '', { tab: 'Token' })
}}
interactive
/>,
],
}}
/>
)
}

const IndexText = styled(Text)`
margin-left: -4px;
`
1 change: 1 addition & 0 deletions packages/atlas/src/components/HotCreatorTokens/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './HotCreatorTokens'
36 changes: 29 additions & 7 deletions packages/atlas/src/components/TopCrtMovers/TopCrtMovers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from '@emotion/styled'
import BN from 'bn.js'
import { useMemo } from 'react'
import { useMemo, useState } from 'react'

import { useGetHotAndColdTokensQuery } from '@/api/queries/__generated__/creatorTokens.generated'
import { SvgEmptyStateIllustration } from '@/assets/illustrations'
Expand Down Expand Up @@ -53,13 +53,17 @@ const tableEmptyState = {
}

export const TopMovingTokens = ({ interval, tableTitle }: { interval: number; tableTitle: string }) => {
const [orderDesc, setOrderDesc] = useState(true)
const { data, loading } = useGetHotAndColdTokensQuery({
variables: {
periodDays: interval,
priceDesc: orderDesc,
limit: 10,
},
})
const columns = getColumns(interval)
const { hotAndColdTokens } = data ?? {}
const { tokensWithPriceChange: _tokensWithPriceChange } = data ?? {}
const tokensWithPriceChange = _tokensWithPriceChange?.filter((token) => token.pricePercentageChange != 0)

const lgMatch = useMediaMatch('lg')
const mappedData = useMemo(() => {
Expand All @@ -84,7 +88,7 @@ export const TopMovingTokens = ({ interval, tableTitle }: { interval: number; ta
),
channelId: null,
}))
: hotAndColdTokens?.map((data, index) => ({
: tokensWithPriceChange?.map((data, index) => ({
index: (
<IndexText variant="t100" as="p" color="colorTextMuted">
#{index + 1}{' '}
Expand Down Expand Up @@ -119,9 +123,9 @@ export const TopMovingTokens = ({ interval, tableTitle }: { interval: number; ta
),
channelId: data.creatorToken.channel?.channel.id,
})) ?? []
}, [hotAndColdTokens, loading])
}, [tokensWithPriceChange, loading])

if (!loading && !hotAndColdTokens) {
if (!loading && !tokensWithPriceChange) {
return null
}

Expand All @@ -132,6 +136,24 @@ export const TopMovingTokens = ({ interval, tableTitle }: { interval: number; ta
type: 'title',
title: tableTitle,
},
sort: {
type: 'toggle-button',
toggleButtonOptionTypeProps: {
onChange: (val) => setOrderDesc(val),
value: orderDesc,
type: 'options',
options: [
{
label: 'Winners',
value: true,
},
{
label: 'Losers',
value: false,
},
],
},
},
}}
contentProps={{
type: 'grid',
Expand All @@ -149,8 +171,8 @@ export const TopMovingTokens = ({ interval, tableTitle }: { interval: number; ta
data={mappedData}
doubleColumn={lgMatch}
onRowClick={(idx) => {
if (hotAndColdTokens?.[idx].creatorToken.id) {
sendUserInteraction('MarketplaceTokenEntry', hotAndColdTokens[idx].creatorToken.id).catch(
if (tokensWithPriceChange?.[idx].creatorToken.id) {
sendUserInteraction('MarketplaceTokenEntry', tokensWithPriceChange[idx].creatorToken.id).catch(
() => undefined
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const COLUMNS: TableProps['columns'] = [
width: 5,
},
{
Header: () => <RightAlignedHeader>7D Volume</RightAlignedHeader>,
Header: () => <RightAlignedHeader>30D Volume</RightAlignedHeader>,
accessor: 'ammVolume',
width: 4,
},
Expand All @@ -50,6 +50,8 @@ export const TopVolumeTokens = () => {
const { data, loading } = useGetTopSellingTokensQuery({
variables: {
periodDays: 30,
volumeDesc: true,
limit: 10,
},
})
const { topSellingToken } = data ?? {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export const AllTokensSection = () => {
cumulativeRevenue,
ammVolume,
liquidity,
weeklyLiqChange,
lastDayPriceChange,
liquidityChange,
priceChange,
marketCap,
channelId,
}) => ({
Expand All @@ -61,8 +61,8 @@ export const AllTokensSection = () => {
tokenTitle: symbol ?? 'N/A',
ammVolume: new BN(ammVolume ?? 0),
liquidity: liquidity ?? 0,
weeklyLiqChange: +(weeklyLiqChange ?? 0),
lastDayPriceChange: +(lastDayPriceChange ?? 0),
liquidityChange: +(liquidityChange ?? 0),
priceChange: +(priceChange ?? 0),
})
) ?? []
const currentSortingTableColumn = Object.entries(sortMappings).find(([, mapping]) => mapping.includes(orderBy))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ export const tableLoadingData = Array.from({ length: 10 }, () => ({
const COLUMNS: TableProps['columns'] = [
{ Header: 'Token', accessor: 'token', width: 2 },
{ Header: 'Date created', accessor: 'createdAt', width: 2 },
{ Header: 'Price % 24h', accessor: 'dailyPriceChange', width: 2 },
{ Header: 'Price % 30d', accessor: 'priceChange', width: 2 },
{ Header: 'Price', accessor: 'price', width: 2 },
{ Header: 'Liq % 7d', accessor: 'liquidityChange', width: 2 },
{ Header: 'Liq % 30d', accessor: 'liquidityChange', width: 2 },
{ Header: 'Liquidity', accessor: 'liquidity', width: 2 },
{ Header: 'Tranding vol.', accessor: 'tradingVolume', width: 2 },
{ Header: 'Status', accessor: 'status', width: 1 },
Expand All @@ -54,9 +54,9 @@ export type MarketplaceToken = {
totalRevenue: BN
holdersNum: number
channelId: string
lastDayPriceChange: number
priceChange: number
ammVolume: BN
weeklyLiqChange: number
liquidityChange: number
liquidity: number
lastPrice: BN
}
Expand Down Expand Up @@ -86,9 +86,9 @@ export const MarketplaceCrtTable = ({ data, emptyState, isLoading, ...tableProps
{formatDate(row.createdAt)}
</Text>
),
dailyPriceChange: (
priceChange: (
<span>
<PercentageChangeIndicator value={row.lastDayPriceChange} />
<PercentageChangeIndicator value={row.priceChange} />
</span>
),
price: (
Expand All @@ -102,7 +102,7 @@ export const MarketplaceCrtTable = ({ data, emptyState, isLoading, ...tableProps
),
liquidityChange: (
<span>
<PercentageChangeIndicator value={row.weeklyLiqChange} />
<PercentageChangeIndicator value={row.liquidityChange} />
</span>
),
liquidity: (
Expand Down

0 comments on commit 84a9f39

Please sign in to comment.