diff --git a/public/images/medals.png b/public/images/medals.png new file mode 100644 index 000000000..efc4da8ba Binary files /dev/null and b/public/images/medals.png differ diff --git a/src/components/creators/TopUsersCard.tsx b/src/components/creators/TopUsersCard.tsx index 737f0288f..ccb553f07 100644 --- a/src/components/creators/TopUsersCard.tsx +++ b/src/components/creators/TopUsersCard.tsx @@ -1,5 +1,6 @@ import { Button, Skeleton } from 'antd' import clsx from 'clsx' +import Link from 'next/link' import { ComponentProps, CSSProperties, useMemo } from 'react' import { IoChevronForward } from 'react-icons/io5' import { useSendEvent } from 'src/providers/AnalyticContext' @@ -11,10 +12,10 @@ import { truncateAddress } from 'src/utils/storage' import { useMyAddress } from '../auth/MyAccountsContext' import { FormatBalance } from '../common/balances' import Avatar from '../profiles/address-views/Avatar' -import ViewProfileLink from '../profiles/ViewProfileLink' import { useIsMobileWidthOrDevice } from '../responsive' -import ViewSpaceLink from '../spaces/ViewSpaceLink' +import { DfImage } from '../utils/DfImage' import { MutedSpan } from '../utils/MutedText' +import { Pluralize } from '../utils/Plularize' import Segment from '../utils/Segment' export type TopUsersCardProps = ComponentProps<'div'> @@ -79,23 +80,31 @@ export default function TopUsersCard({ ...props }: TopUsersCardProps) { style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr 1fr' : '1fr' }} >
- Stakers -
- {data.stakers.map((staker, i) => ( - - ))} -
+ Likers + {data.stakers.length < 3 ? ( + + ) : ( +
+ {data.stakers.map((staker, i) => ( + + ))} +
+ )}
Creators -
- {data?.creators.map((creator, i) => ( - - ))} -
+ {data.creators.length < 3 ? ( + + ) : ( +
+ {data.creators.map((creator, i) => ( + + ))} +
+ )}
{!isMobile &&
{seeMoreButton}
} @@ -121,7 +130,15 @@ export default function TopUsersCard({ ...props }: TopUsersCardProps) { ) } -function UserInfo({ rank, user }: { rank: number; user: { address: string; reward: string } }) { +function UserInfo({ + rank, + user, + type, +}: { + rank: number + user: { address: string; reward?: string; count?: number } + type: 'staker' | 'creator' +}) { const profile = useSelectProfile(user.address) const avatar = ( @@ -145,7 +162,7 @@ function UserInfo({ rank, user }: { rank: number; user: { address: string; rewar return (
- {profile ? : avatar} + {avatar} {[1, 2, 3].includes(rank) && (
- {profile ? ( - - ) : ( - - )} + + {name} +
- + {type === 'creator' ? ( + + ) : ( + + + + )}
) } +function NoUsersContent({ text }: { text: string }) { + return ( +
+ + + {text} + +
+ ) +} + function Medal({ rank, ...props }: ComponentProps<'div'> & { rank: 1 | 2 | 3 }) { const rankStyles: Record = { 1: { diff --git a/src/components/utils/datahub/leaderboard.ts b/src/components/utils/datahub/leaderboard.ts index ed53c0618..6d5259d27 100644 --- a/src/components/utils/datahub/leaderboard.ts +++ b/src/components/utils/datahub/leaderboard.ts @@ -1,3 +1,4 @@ +import dayjs from 'dayjs' import gql from 'graphql-tag' import { GeneralStatistics } from 'src/rtk/features/leaderboard/generalStatisticsSlice' import { LeaderboardData } from 'src/rtk/features/leaderboard/leaderboardSlice' @@ -6,19 +7,12 @@ import { UserStatistics } from 'src/rtk/features/leaderboard/userStatisticsSlice import { datahubQueryRequest, getDayAndWeekTimestamp } from './utils' const GET_TOP_USERS = gql` - query GetTopUsers($from: String!) { - staker: activeStakingAddressesRankedByRewardsForPeriod( - args: { - filter: { period: WEEK, role: STAKER, timestamp: $from } - limit: 3 - offset: 0 - order: DESC - } + query GetTopUsers($from: String!, $fromTimestamp: String!) { + staker: activeStakingStakersRankedBySuperLikesForPeriod( + args: { fromTime: $fromTimestamp, limit: 3 } ) { - data { - address - reward - } + address + count } creator: activeStakingAddressesRankedByRewardsForPeriod( args: { @@ -37,14 +31,19 @@ const GET_TOP_USERS = gql` ` export async function getTopUsers(): Promise { const { week } = getDayAndWeekTimestamp() + let startOfWeekTimestamp = dayjs.utc().startOf('day') + let daysToMonday = startOfWeekTimestamp.day() - 1 + if (daysToMonday < 0) { + daysToMonday += 7 + } + startOfWeekTimestamp = startOfWeekTimestamp.subtract(daysToMonday, 'day') + const res = await datahubQueryRequest< { staker: { - data: { - address: string - reward: string - }[] - } + address: string + count: number + }[] creator: { data: { address: string @@ -52,10 +51,13 @@ export async function getTopUsers(): Promise { }[] } }, - { from: string } + { from: string; fromTimestamp: string } >({ query: GET_TOP_USERS, - variables: { from: week.toString() }, + variables: { + from: week.toString(), + fromTimestamp: startOfWeekTimestamp.valueOf().toString(), + }, }) return { @@ -63,9 +65,9 @@ export async function getTopUsers(): Promise { address, reward, })), - stakers: res.data.staker.data.map(({ address, reward }) => ({ + stakers: res.data.staker.map(({ address, count }) => ({ address, - reward, + count, })), } } diff --git a/src/rtk/features/leaderboard/topUsersSlice.ts b/src/rtk/features/leaderboard/topUsersSlice.ts index b776bf027..e1d33ca90 100644 --- a/src/rtk/features/leaderboard/topUsersSlice.ts +++ b/src/rtk/features/leaderboard/topUsersSlice.ts @@ -7,9 +7,10 @@ import { createSimpleFetchWrapper } from 'src/rtk/app/wrappers' import { fetchProfileSpaces } from '../profiles/profilesSlice' type User = { address: string; reward: string } +type UserByLike = { address: string; count: number } export type TopUsers = { creators: User[] - stakers: User[] + stakers: UserByLike[] } const sliceName = 'topUsers'