Skip to content

Commit

Permalink
Merge pull request #654 from dappforce/deploy/leaderboard
Browse files Browse the repository at this point in the history
Add leaderboard page
  • Loading branch information
samchuk-vlad authored May 7, 2024
2 parents 2a4ce8f + 84ae8bd commit 32e7e2c
Show file tree
Hide file tree
Showing 31 changed files with 1,959 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ jobs:
GH_NEXT_PUBLIC_FIREBASE_APP_ID=1:581626459774:web:6b7098eb48c0b142f50a2f
GH_NEXT_PUBLIC_SUBSTRATE_URL=https://para.subsocial.network
GH_NEXT_PUBLIC_SUBSTRATE_WSS=wss://para.subsocial.network
GH_NEXT_PUBLIC_DATAHUB_QUERY_URL=https://ownership-pallet-data-hub-core.subsocial.network/graphql
GH_NEXT_PUBLIC_DATAHUB_QUERY_URL=https://sub-data-hub.subsocial.network/graphql
GH_NEXT_PUBLIC_DATAHUB_SUBSCRIPTION_URL=wss://ownership-pallet-data-hub-core.subsocial.network/graphql-ws
GH_DATAHUB_QUEUE_URL=https://ownership-pallet-data-hub-queue.subsocial.network/graphql
GH_NOTIFICATIONS_URL=https://ownership-pallet-notif-data-hub-core.subsocial.network/graphql
Expand Down
Binary file added src/assets/graphics/coins.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/graphics/medals.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
153 changes: 108 additions & 45 deletions src/components/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,49 @@ import { mutedTextColorStyles } from './content-staking/utils/commonStyles'

export type Column = {
index: string
name: string
name?: string
align?: 'left' | 'center' | 'right'
className?: string
}

type TableProps = {
columns: Column[]
data: any[]
headerClassName?: string
className?: string
withDivider?: boolean
onRowClick?: (item: any) => void
}

const Table = ({ columns, data }: TableProps) => {
const Table = ({
columns,
data,
headerClassName,
className,
withDivider = true,
onRowClick,
}: TableProps) => {
return (
<div className={cx('relative overflow-x-auto rounded-2xl', sectionBg)}>
<div
className={cx(
'relative overflow-x-auto rounded-2xl',
sectionBg,
className
)}
>
<table className='w-full text-left'>
<thead
className={cx(
'bg-slate-50 text-base backdrop-blur-xl dark:bg-white/5',
mutedTextColorStyles
)}
>
<tr>
{columns.map(({ name, index, align }, i) => (
<th
key={index}
scope='col'
className={cx(
'px-6 py-4 font-normal',
`text-${align || 'left'}`
)}
>
{name}
</th>
))}
</tr>
</thead>
<TableHeader columns={columns} headerClassName={headerClassName} />
<tbody>
{data.map((item, i) => {
return (
<tr
<TableRow
key={i}
className={cx(
'border-b border-[#D4E2EF] dark:border-white/20',
{
['border-none']: i === data.length - 1,
}
)}
>
{columns.map(({ index, align }, j) => {
const value = item[index]

return (
<td
key={`${index}-${j}`}
className={cx('px-6 py-4', `text-${align || 'left'}`)}
>
{value}
</td>
)
})}
</tr>
columns={columns}
item={item}
withDivider={withDivider}
showLastDivider={i === data.length - 1}
onRowClick={onRowClick}
/>
)
})}
</tbody>
Expand All @@ -71,4 +55,83 @@ const Table = ({ columns, data }: TableProps) => {
)
}

type TableColumnsProps = {
columns: Column[]
headerClassName?: string
}

export const TableHeader = ({
columns,
headerClassName,
}: TableColumnsProps) => {
return (
<thead
className={cx(
'bg-slate-50 text-base backdrop-blur-xl dark:bg-white/5',
mutedTextColorStyles,
headerClassName
)}
>
<tr>
{columns.map(({ name, index, align, className }) => (
<th
key={index}
scope='col'
className={cx(
'px-6 py-4 font-normal',
`text-${align || 'left'}`,
className
)}
>
{name}
</th>
))}
</tr>
</thead>
)
}

type TableRowProps = {
columns: Column[]
item: any & { className?: string }
withDivider?: boolean
showLastDivider?: boolean
onRowClick?: (item: any) => void
className?: string
}

export const TableRow = ({
columns,
item,
withDivider,
showLastDivider,
onRowClick,
className,
}: TableRowProps) => {
return (
<tr
className={cx(item?.className, className, {
['border-b border-[#D4E2EF] dark:border-white/20']: withDivider,
['border-none']: showLastDivider,
['cursor-pointer overflow-hidden hover:bg-[#EEF2FF] dark:hover:bg-slate-700']:
onRowClick,
})}
onClick={() => onRowClick?.(item)}
>
{columns.map(({ index, align, className }, j) => {
const value = item[index]

return (
<td
key={`${index}-${j}`}
className={cx('px-6 py-4', `text-${align || 'left'}`, className)}
>
{value}
</td>
)
})}
</tr>
)
}

export default Table
21 changes: 15 additions & 6 deletions src/components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type Tab = {
id: string
text: string | ReactNode
content: (changeTab: (selectedTab: number) => void) => JSX.Element
isHidden?: boolean
}
export type TabsProps = ComponentProps<'div'> & {
tabStyle?: 'buttons' | 'texts'
Expand All @@ -21,7 +22,7 @@ export type TabsProps = ComponentProps<'div'> & {
hideBeforeHashLoaded?: boolean
manualTabControl?: {
selectedTab: number
setSelectedTab: (selectedTab: number) => void
setSelectedTab: (selectedTab: number, tabId?: string) => void
}
}

Expand Down Expand Up @@ -49,17 +50,19 @@ export default function Tabs({

const hash = window.location.hash
const index = tabs.findIndex(({ id }) => `#${id}` === hash)
if (index > -1) setSelectedTab(index)
const id = tabs[index]?.id
if (index > -1) setSelectedTab(index, id)

setIsHashLoaded(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

const changeTab = (index: number) => {
setSelectedTab(index)
const id = tabs[index].id

setSelectedTab(index, id)

if (withHashIntegration) {
const id = tabs[index].id
replaceUrl(`#${id}`)
}
}
Expand All @@ -73,7 +76,12 @@ export default function Tabs({
return (
<Tab.Group
selectedIndex={usedSelectedTab === -1 ? tabs.length : usedSelectedTab}
onChange={setSelectedTab}
manual
onChange={(index) => {
const id = tabs[index]?.id

setSelectedTab(index, id)
}}
>
<Tab.List
as={component}
Expand All @@ -83,12 +91,13 @@ export default function Tabs({
props.className
)}
>
{tabs.map(({ text, id }, idx) => (
{tabs.map(({ text, id, isHidden }, idx) => (
<Tab key={id} as={Fragment}>
{({ selected }) => {
return (
<span
className={cx(
isHidden && '!hidden',
'group relative block cursor-pointer rounded-t-2xl px-2 outline-none after:absolute after:bottom-0 after:left-0 after:h-[90%] after:w-full after:rounded-t-2xl after:bg-background-light after:opacity-0 after:transition-opacity sm:px-3',
'border-collapse focus-visible:after:opacity-100',
tabStyle === 'buttons' &&
Expand Down
3 changes: 2 additions & 1 deletion src/components/layouts/CreatorSidebar/RewardInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Skeleton } from '@/components/SkeletonFallback'
import getAmountRange from '@/components/content-staking/utils/getAmountRangeForAnalytics'
import PopOver from '@/components/floating/PopOver'
import { getLeaderboardLink } from '@/components/leaderboard/utils'
import {
PostRewards,
RewardReport,
Expand Down Expand Up @@ -96,8 +97,8 @@ export default function RewardInfo({ size, ...props }: RewardInfoProps) {

<CustomLink
className='flex items-center justify-center gap-2 px-4 py-3.5 font-medium text-text-primary'
href={`${getLeaderboardLink(myAddress)}?role=staker`}
forceHardNavigation
href={`/leaderboard/${myAddress}?role=staker`}
onClick={() => {
sendEvent('leaderboard_my_stats_opened', {
myStats: true,
Expand Down
12 changes: 11 additions & 1 deletion src/components/layouts/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type DefaultLayoutProps = ComponentProps<'div'> & {
withFixedHeight?: boolean
withSidebar?: boolean
withSidebarBorder?: boolean
withRightSidebar?: boolean
}

export default function DefaultLayout({
Expand All @@ -24,6 +25,7 @@ export default function DefaultLayout({
withBackButton,
withFixedHeight,
withSidebar,
withRightSidebar = true,
style,
...props
}: DefaultLayoutProps) {
Expand Down Expand Up @@ -65,7 +67,15 @@ export default function DefaultLayout({
<Sidebar />
</div>
<div className='flex-1'>{children}</div>
<CreatorSidebar className='hidden h-fit max-h-none w-[275px] py-4 lg:flex' />
{withRightSidebar && (
<div
className={cx(
'sticky top-14 hidden h-[calc(100dvh_-_3.5rem)] w-[275px] py-4 lg:block'
)}
>
<CreatorSidebar />
</div>
)}
</div>
) : (
children
Expand Down
3 changes: 2 additions & 1 deletion src/components/layouts/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { MdOutlineLeaderboard } from 'react-icons/md'
import { RiLineChartLine } from 'react-icons/ri'
import { TbCoins, TbWorld } from 'react-icons/tb'
import { TiFlashOutline } from 'react-icons/ti'
import { getLeaderboardLink } from '../leaderboard/utils'
import CustomLink from '../referral/CustomLink'

export default function Sidebar() {
Expand Down Expand Up @@ -40,7 +41,7 @@ export default function Sidebar() {
<SidebarItem
icon={MdOutlineLeaderboard}
title='Leaderboard'
href='/leaderboard'
href={getLeaderboardLink(myAddress)}
forceHardNavigation
/>
<SidebarItem
Expand Down
52 changes: 52 additions & 0 deletions src/components/leaderboard/GlobalStats/GlobalStatsDashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { getGeneralStatisticsQuery } from '@/services/datahub/leaderboard/query'
import { UserStatsCard } from '../MyStats/LeaderboardStatsData'

const GlobalStatsDashboard = () => {
const { data: generalStats, isLoading } = getGeneralStatisticsQuery.useQuery(
{}
)

const { stakersEarnedTotal, creatorsEarnedTotal, creatorsLiked, postsLiked } =
generalStats || {}

const data = [
{
title: 'Total posts and comments liked',
value: postsLiked,
tooltipText:
'The total number of individual posts or comments that were liked at least one time this week',
rank: null,
},
{
title: 'Total SUB earned by stakers',
value: stakersEarnedTotal,
tooltipText:
'The total amount of SUB rewards earned by stakers on Subsocial this week',
rank: null,
},
{
title: 'Total creators liked',
value: creatorsLiked,
tooltipText:
'The total number of individual creators that had one of their posts or comments liked this week',
rank: null,
},
{
title: 'Total SUB earned by creators',
value: creatorsEarnedTotal,
tooltipText:
'The total amount of SUB rewards earned by creators on Subsocial this week',
rank: null,
},
]

return (
<>
{data.map((item, index) => (
<UserStatsCard key={index} {...item} isLoading={isLoading} />
))}
</>
)
}

export default GlobalStatsDashboard
Loading

0 comments on commit 32e7e2c

Please sign in to comment.