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 = () => {
{
)}
-
+