diff --git a/packages/atlas/src/components/TopEarningChannels/TopEarningChannels.tsx b/packages/atlas/src/components/TopEarningChannels/TopEarningChannels.tsx new file mode 100644 index 0000000000..91dc965d12 --- /dev/null +++ b/packages/atlas/src/components/TopEarningChannels/TopEarningChannels.tsx @@ -0,0 +1,161 @@ +import BN from 'bn.js' +import { useMemo } from 'react' + +import { useBasicChannels } from '@/api/hooks/channel' +import { ChannelOrderByInput } from '@/api/queries/__generated__/baseTypes.generated' +import { BasicChannelFieldsFragment } from '@/api/queries/__generated__/fragments.generated' +import { SvgActionCreatorToken, SvgActionVerified } from '@/assets/icons' +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 { Avatar } from '../Avatar' +import { + JoyAmountWrapper, + SenderItemIconsWrapper, + SkeletonChannelContainer, + StyledLink, + StyledListItem, + StyledTable, +} from '../TopSellingChannelsTable/TopSellingChannelsTable.styles' + +const COLUMNS: TableProps['columns'] = [ + { + Header: '', + accessor: 'index', + width: 1, + }, + { + Header: 'CHANNEL', + accessor: 'channel', + width: 9, + }, + { + Header: () => SALES VOLUME, + accessor: 'salesVolume', + width: 4, + }, +] + +const tableEmptyState = { + title: 'No channels found', + description: 'No top earning channels with minted token have been found.', + icon: , +} + +export const TopEarningChannels = ({ withCrtOnly }: { withCrtOnly?: boolean }) => { + const { channels, loading } = useBasicChannels({ + limit: 10, + orderBy: [ChannelOrderByInput.CumulativeRevenueDesc], + where: { + cumulativeRevenue_gt: '0', + ...(withCrtOnly ? { creatorToken_isNull: false } : {}), + }, + }) + + const lgMatch = useMediaMatch('lg') + const mappedData: TableProps['data'] = useMemo(() => { + return loading + ? Array.from({ length: 10 }, () => ({ + index: null, + channel: ( + + + + + ), + salesVolume: , + })) + : channels?.map((data, index) => ({ + index: ( + + {index + 1} + + ), + salesVolume: ( + + } + variant="t200-strong" + as="p" + value={new BN(data.cumulativeRevenue)} + margin={{ left: 1 }} + format="short" + withDenomination + denominationAlign="right" + /> + + ), + channel: , + })) ?? [] + }, [channels, loading]) + + if (!loading && !channels) { + return null + } + + return ( +
, + ], + }} + /> + ) +} + +const Channel = ({ channel }: { channel: BasicChannelFieldsFragment }) => { + const hasCreatorToken = !!channel.creatorToken?.token.id + // todo to be implemented + const verified = false + return ( + + } + label={channel.title} + isInteractive={false} + nodeEnd={ + + {hasCreatorToken && ( + + + + )} + {verified && ( + + + + )} + + } + /> + + ) +} diff --git a/packages/atlas/src/components/TopEarningChannels/index.ts b/packages/atlas/src/components/TopEarningChannels/index.ts new file mode 100644 index 0000000000..5e4d9805fb --- /dev/null +++ b/packages/atlas/src/components/TopEarningChannels/index.ts @@ -0,0 +1 @@ +export * from './TopEarningChannels' diff --git a/packages/atlas/src/components/_crt/AllTokensSection/AllTokensSection.tsx b/packages/atlas/src/components/_crt/AllTokensSection/AllTokensSection.tsx index 3dfa3ba339..274a73e122 100644 --- a/packages/atlas/src/components/_crt/AllTokensSection/AllTokensSection.tsx +++ b/packages/atlas/src/components/_crt/AllTokensSection/AllTokensSection.tsx @@ -29,7 +29,7 @@ export const AllTokensSection = () => { const tableData = tokens?.map(({ createdAt, accountsNum, lastPrice, totalSupply, status, symbol, channel }) => ({ createdAt: new Date(createdAt), - totalRevenue: 0, + totalRevenue: new BN(channel?.channel.cumulativeRevenue ?? 0), holdersNum: accountsNum, isVerified: false, marketCap: lastPrice && totalSupply ? hapiBnToTokenNumber(new BN(lastPrice).mul(new BN(totalSupply))) ?? 0 : 0, diff --git a/packages/atlas/src/components/_crt/CrtCard/CrtCard.tsx b/packages/atlas/src/components/_crt/CrtCard/CrtCard.tsx index 604e680fdb..b1cd189cda 100644 --- a/packages/atlas/src/components/_crt/CrtCard/CrtCard.tsx +++ b/packages/atlas/src/components/_crt/CrtCard/CrtCard.tsx @@ -1,6 +1,7 @@ import { css } from '@emotion/react' import styled from '@emotion/styled' import { ReactElement, useMemo } from 'react' +import { Link } from 'react-router-dom' import { SvgActionAuction, SvgActionMarket, SvgActionNotForSale, SvgActionNotifications } from '@/assets/icons' import { Avatar } from '@/components/Avatar' @@ -11,6 +12,7 @@ import { Button } from '@/components/_buttons/Button' import { CrtMainInfo, CrtMainInfoProps } from '@/components/_crt/CrtBasicInfoWidget' import { SkeletonLoader } from '@/components/_loaders/SkeletonLoader' import { DetailsContent, DetailsContentProps } from '@/components/_nft/NftTile' +import { absoluteRoutes } from '@/config/routes' import { cVar, sizes } from '@/styles' type SaleProps = { @@ -27,6 +29,7 @@ export type CrtSaleTypes = MarketProps | SaleProps | { type: 'inactive' } export type CrtCardProps = { marketCap?: number + channelId: string channelRevenue?: number size?: 'medium' | 'small' status?: CrtSaleTypes @@ -36,6 +39,7 @@ export type CrtCardProps = { export const CrtCard = ({ channelRevenue, + channelId, marketCap, size, status, @@ -165,7 +169,7 @@ export const CrtCard = ({ } return ( - + } variant="secondary" rounded size={isSmall ? 'medium' : 'small'} /> - + {details.map((detail, idx) => ( ))} - + ) } +const Container = styled(Link)` + display: flex; + flex-direction: column; + text-decoration: none; + + :hover { + opacity: 0.85; + } + + cursor: pointer; +` + const StyledDetailsContent = styled(DetailsContent)<{ isInactive?: boolean }>` display: flex; flex-direction: column; diff --git a/packages/atlas/src/components/_crt/MarketplaceCrtTable/MarketplaceCrtTable.tsx b/packages/atlas/src/components/_crt/MarketplaceCrtTable/MarketplaceCrtTable.tsx index 5f7a995b0c..3bb7491088 100644 --- a/packages/atlas/src/components/_crt/MarketplaceCrtTable/MarketplaceCrtTable.tsx +++ b/packages/atlas/src/components/_crt/MarketplaceCrtTable/MarketplaceCrtTable.tsx @@ -1,4 +1,5 @@ import styled from '@emotion/styled' +import BN from 'bn.js' import { useMemo } from 'react' import { TokenStatus } from '@/api/queries/__generated__/baseTypes.generated' @@ -44,7 +45,7 @@ export type MarketplaceToken = { status: TokenStatus createdAt: Date marketCap: number - totalRevenue: number + totalRevenue: BN holdersNum: number channelId: string } diff --git a/packages/atlas/src/views/viewer/MarketplaceView/tabs/MarketplaceCrtTab.tsx b/packages/atlas/src/views/viewer/MarketplaceView/tabs/MarketplaceCrtTab.tsx index 329af25798..76714134c1 100644 --- a/packages/atlas/src/views/viewer/MarketplaceView/tabs/MarketplaceCrtTab.tsx +++ b/packages/atlas/src/views/viewer/MarketplaceView/tabs/MarketplaceCrtTab.tsx @@ -6,7 +6,7 @@ import { useGetBasicCreatorTokensQuery } from '@/api/queries/__generated__/creat import { LimitedWidthContainer } from '@/components/LimitedWidthContainer' import { MarketplaceCarousel } from '@/components/NftCarousel/MarketplaceCarousel' import { Section } from '@/components/Section/Section' -import { TopSellingChannelsTable } from '@/components/TopSellingChannelsTable' +import { TopEarningChannels } from '@/components/TopEarningChannels' import { AllTokensSection } from '@/components/_crt/AllTokensSection' import { CrtCard, CrtSaleTypes } from '@/components/_crt/CrtCard/CrtCard' import { useMediaMatch } from '@/hooks/useMediaMatch' @@ -29,7 +29,7 @@ export const MarketplaceCrtTab = () => { const filteredTokens = data?.creatorTokens.filter((token) => !!token.trailerVideo.length).slice(0, 10) ?? [] const featuredCrts = - filteredTokens.map( + data?.creatorTokens.map( ({ id, symbol, channel, totalSupply, accountsNum, lastPrice, currentAmmSale, description, currentSale }) => { const status: CrtSaleTypes = currentSale ? { @@ -49,6 +49,7 @@ export const MarketplaceCrtTab = () => { { )} - +