2023-03-06 00:59:14 -08:00
|
|
|
import ButtonGroup from '@components/forms/ButtonGroup'
|
2023-03-19 20:19:53 -07:00
|
|
|
import { LinkButton } from '@components/shared/Button'
|
|
|
|
import SheenLoader from '@components/shared/SheenLoader'
|
2023-03-06 00:59:14 -08:00
|
|
|
import { useQuery } from '@tanstack/react-query'
|
|
|
|
import { useTranslation } from 'next-i18next'
|
2023-03-19 20:19:53 -07:00
|
|
|
import { useState } from 'react'
|
2023-03-06 00:59:14 -08:00
|
|
|
import { MANGO_DATA_API_URL } from 'utils/constants'
|
|
|
|
import LeaderboardTable from './LeaderboardTable'
|
|
|
|
|
2023-03-14 03:50:42 -07:00
|
|
|
export interface LeaderboardItem {
|
|
|
|
date_hour: string
|
|
|
|
mango_account: string
|
|
|
|
pnl: number
|
|
|
|
start_date_hour: string
|
|
|
|
wallet_pk: string
|
|
|
|
profile_image_url?: string
|
|
|
|
profile_name?: string
|
|
|
|
trader_category?: string
|
|
|
|
}
|
|
|
|
|
2023-03-06 00:59:14 -08:00
|
|
|
const LeaderboardPage = () => {
|
2023-03-15 01:35:29 -07:00
|
|
|
const { t } = useTranslation(['common', 'leaderboard'])
|
2023-03-06 00:59:14 -08:00
|
|
|
const [daysToShow, setDaysToShow] = useState('ALLTIME')
|
2023-03-19 20:19:53 -07:00
|
|
|
const [offset, setOffset] = useState(0)
|
|
|
|
const [leaderboardData, setLeaderboardData] = useState([])
|
|
|
|
|
|
|
|
const fetchLeaderboard = async () => {
|
|
|
|
try {
|
|
|
|
const data = await fetch(
|
|
|
|
`${MANGO_DATA_API_URL}/leaderboard-pnl?over_period=${daysToShow}&offset=${offset}`
|
|
|
|
)
|
|
|
|
const leaderboardRes = await data.json()
|
|
|
|
const profileData = await Promise.all(
|
|
|
|
leaderboardRes.map((r: LeaderboardItem) =>
|
|
|
|
fetch(
|
|
|
|
`${MANGO_DATA_API_URL}/user-data/profile-details?wallet-pk=${r.wallet_pk}`
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
const profileRes = await Promise.all(profileData.map((d) => d.json()))
|
|
|
|
const combinedRes = leaderboardRes.map(
|
|
|
|
(r: LeaderboardItem, i: number) => ({
|
|
|
|
...r,
|
|
|
|
...profileRes[i],
|
|
|
|
})
|
|
|
|
)
|
|
|
|
setLeaderboardData(leaderboardData.concat(combinedRes))
|
|
|
|
return combinedRes
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Failed to fetch leaderboard', e)
|
|
|
|
}
|
|
|
|
}
|
2023-03-06 00:59:14 -08:00
|
|
|
|
2023-03-19 20:19:53 -07:00
|
|
|
const { isLoading, isFetching } = useQuery(
|
|
|
|
['leaderboard', daysToShow, offset],
|
|
|
|
() => fetchLeaderboard(),
|
2023-03-14 03:50:42 -07:00
|
|
|
{
|
|
|
|
cacheTime: 1000 * 60 * 10,
|
|
|
|
staleTime: 1000 * 60,
|
|
|
|
retry: 3,
|
2023-03-19 20:19:53 -07:00
|
|
|
refetchOnWindowFocus: false,
|
2023-03-14 03:50:42 -07:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
const handleDaysToShow = (days: string) => {
|
2023-03-19 20:19:53 -07:00
|
|
|
setLeaderboardData([])
|
|
|
|
setOffset(0)
|
2023-03-14 03:50:42 -07:00
|
|
|
setDaysToShow(days)
|
|
|
|
}
|
2023-03-06 00:59:14 -08:00
|
|
|
|
2023-03-19 20:19:53 -07:00
|
|
|
const handleShowMore = () => {
|
|
|
|
setOffset(offset + 20)
|
|
|
|
}
|
|
|
|
|
|
|
|
const loading = isLoading || isFetching
|
2023-03-06 00:59:14 -08:00
|
|
|
|
|
|
|
return (
|
2023-03-15 01:35:29 -07:00
|
|
|
<div className="p-4 md:p-10 lg:px-0">
|
2023-03-06 00:59:14 -08:00
|
|
|
<div className="grid grid-cols-12">
|
|
|
|
<div className="col-span-12 lg:col-span-8 lg:col-start-3">
|
2023-03-14 03:50:42 -07:00
|
|
|
<div className="mb-6 flex flex-col md:flex-row md:items-center md:justify-between">
|
2023-03-15 01:35:29 -07:00
|
|
|
<div>
|
|
|
|
<h1 className="mb-2">{t('leaderboard')}</h1>
|
|
|
|
<p className="mb-4 md:mb-0">
|
|
|
|
{t('leaderboard:leaderboard-desc')}
|
|
|
|
</p>
|
|
|
|
</div>
|
2023-03-14 03:50:42 -07:00
|
|
|
<div className="w-full md:w-48">
|
|
|
|
<ButtonGroup
|
|
|
|
activeValue={daysToShow}
|
|
|
|
disabled={isLoading}
|
|
|
|
onChange={(v) => handleDaysToShow(v)}
|
|
|
|
names={['24h', '7d', t('all')]}
|
|
|
|
values={['1DAY', '1WEEK', 'ALLTIME']}
|
2023-03-06 00:59:14 -08:00
|
|
|
/>
|
2023-03-14 03:50:42 -07:00
|
|
|
</div>
|
2023-03-06 00:59:14 -08:00
|
|
|
</div>
|
2023-03-19 20:19:53 -07:00
|
|
|
{leaderboardData.length ? (
|
|
|
|
<LeaderboardTable data={leaderboardData} loading={loading} />
|
|
|
|
) : loading ? (
|
|
|
|
<div className="space-y-2">
|
|
|
|
{[...Array(20)].map((x, i) => (
|
|
|
|
<SheenLoader className="flex flex-1" key={i}>
|
|
|
|
<div className="h-16 w-full rounded-md bg-th-bkg-2" />
|
|
|
|
</SheenLoader>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
) : null}
|
|
|
|
{offset < 100 ? (
|
|
|
|
<LinkButton className="mx-auto mt-6" onClick={handleShowMore}>
|
|
|
|
{t('show-more')}
|
|
|
|
</LinkButton>
|
2023-03-14 03:50:42 -07:00
|
|
|
) : null}
|
2023-03-06 00:59:14 -08:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default LeaderboardPage
|