add projected next season tier
This commit is contained in:
parent
3aa65f7f75
commit
1b45a5f677
|
@ -18,7 +18,7 @@ const RewardsPage = () => {
|
|||
const { showClaim } = useIsAllClaimed(prevSeason, publicKey)
|
||||
|
||||
return !showLeaderboards ? (
|
||||
showClaim ? (
|
||||
!showClaim ? (
|
||||
<ClaimPage />
|
||||
) : (
|
||||
<Season setShowLeaderboards={setShowLeaderboards} />
|
||||
|
|
|
@ -26,6 +26,38 @@ import MedalIcon from '@components/icons/MedalIcon'
|
|||
import FormatNumericValue from '@components/shared/FormatNumericValue'
|
||||
import { usePlausible } from 'next-plausible'
|
||||
import { TelemetryEvents } from 'utils/telemetry'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { MANGO_DATA_API_URL } from 'utils/constants'
|
||||
import {
|
||||
ActivityFeed,
|
||||
isSpotTradeActivityFeedItem,
|
||||
isSwapActivityFeedItem,
|
||||
} from 'types'
|
||||
import Tooltip from '@components/shared/Tooltip'
|
||||
|
||||
const fetchSeasonTradesData = async (
|
||||
startDate: string,
|
||||
mangoAccountPk: string,
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/activity-feed?mango-account=${mangoAccountPk}&start-date=${startDate}`,
|
||||
)
|
||||
const parsedResponse = await response.json()
|
||||
|
||||
if (parsedResponse && parsedResponse?.length) {
|
||||
const swapsAndSpot = parsedResponse.filter(
|
||||
(data: ActivityFeed) =>
|
||||
data.activity_type === 'swap' ||
|
||||
data.activity_type === 'openbook_trade',
|
||||
)
|
||||
return swapsAndSpot
|
||||
} else return []
|
||||
} catch (e) {
|
||||
console.error('Failed to load season trades data', e)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const Season = ({
|
||||
setShowLeaderboards,
|
||||
|
@ -48,6 +80,47 @@ const Season = ({
|
|||
refetch,
|
||||
} = useAccountPointsAndRank(mangoAccountAddress, seasonData?.season_id)
|
||||
|
||||
const { data: seasonTradesData } = useQuery(
|
||||
['season-trades-data', seasonData?.season_start],
|
||||
() => fetchSeasonTradesData(seasonData!.season_start, mangoAccountAddress),
|
||||
{
|
||||
cacheTime: 1000 * 60 * 10,
|
||||
staleTime: 1000 * 60,
|
||||
retry: 3,
|
||||
refetchOnWindowFocus: false,
|
||||
enabled: !!(seasonData?.season_start && mangoAccountAddress),
|
||||
},
|
||||
)
|
||||
|
||||
const averageTradeValue = useMemo(() => {
|
||||
if (!seasonTradesData || !seasonTradesData?.length) return 0
|
||||
const notionalValues = []
|
||||
for (const trade of seasonTradesData) {
|
||||
const { activity_details } = trade
|
||||
if (isSwapActivityFeedItem(trade)) {
|
||||
const value =
|
||||
activity_details.swap_in_amount * activity_details.swap_in_price_usd
|
||||
notionalValues.push(value)
|
||||
}
|
||||
if (isSpotTradeActivityFeedItem(trade)) {
|
||||
const value = activity_details.size * activity_details.price
|
||||
notionalValues.push(value)
|
||||
}
|
||||
}
|
||||
const totalValue = notionalValues.reduce((a, c) => a + c, 0)
|
||||
const averageValue = totalValue / notionalValues.length
|
||||
return averageValue
|
||||
}, [seasonTradesData])
|
||||
|
||||
const projectedTier = useMemo(() => {
|
||||
if (!accountTier?.tier) return ''
|
||||
if (accountTier.tier === 'bot') {
|
||||
return 'bot'
|
||||
} else if (averageTradeValue > 1000) {
|
||||
return 'whale'
|
||||
} else return 'mango'
|
||||
}, [accountTier, averageTradeValue])
|
||||
|
||||
useEffect(() => {
|
||||
if (!topAccountsTier && !loadingAccountTier) {
|
||||
setTopAccountsTier(accountTier?.tier.toLowerCase() || 'mango')
|
||||
|
@ -171,9 +244,7 @@ const Season = ({
|
|||
</div>
|
||||
<div className="order-1 col-span-12 lg:order-2 lg:col-span-5">
|
||||
<div className="mb-4 rounded-2xl border border-th-bkg-3 p-6">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="rewards-h2">Your Points</h2>
|
||||
</div>
|
||||
<h2 className="rewards-h2 mb-4">Your Points</h2>
|
||||
<div className="mb-4 flex h-14 w-full items-center rounded-xl bg-th-bkg-2 px-3">
|
||||
{!loadingAccountPointsAndRank ? (
|
||||
accountPointsAndRank?.total_points ? (
|
||||
|
@ -264,6 +335,35 @@ const Season = ({
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4 rounded-2xl border border-th-bkg-3 p-6">
|
||||
<h2 className="rewards-h2 mb-4">Activity</h2>
|
||||
<div className="border-b border-th-bkg-3">
|
||||
<div className="flex items-center justify-between border-t border-th-bkg-3 px-3 py-2">
|
||||
<p className="rewards-p">Average Trade Value</p>
|
||||
<span className="font-rewards text-lg text-th-active">
|
||||
<FormatNumericValue value={averageTradeValue} isUsd />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between border-t border-th-bkg-3 px-3 py-2">
|
||||
<Tooltip content="Your projected tier for next season. This is based on your average trade value">
|
||||
<p className="rewards-p tooltip-underline">Projected Tier</p>
|
||||
</Tooltip>
|
||||
<span className="font-rewards text-lg text-th-active">
|
||||
{!loadingAccountTier ? (
|
||||
projectedTier ? (
|
||||
<span className="capitalize">{projectedTier}</span>
|
||||
) : (
|
||||
'–'
|
||||
)
|
||||
) : (
|
||||
<SheenLoader>
|
||||
<div className="h-4 w-12 rounded-sm bg-th-bkg-3" />
|
||||
</SheenLoader>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-2xl border border-th-bkg-3 p-6">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="rewards-h2">Top Accounts</h2>
|
||||
|
|
|
@ -285,6 +285,28 @@ export interface SpotTradeActivity {
|
|||
symbol: string
|
||||
}
|
||||
|
||||
export interface SwapHistoryItem {
|
||||
block_datetime: string
|
||||
mango_account: string
|
||||
signature: string
|
||||
swap_in_amount: number
|
||||
swap_in_loan: number
|
||||
swap_in_loan_origination_fee: number
|
||||
swap_in_price_usd: number
|
||||
swap_in_symbol: string
|
||||
swap_out_amount: number
|
||||
loan: number
|
||||
loan_origination_fee: number
|
||||
swap_out_price_usd: number
|
||||
swap_out_symbol: string
|
||||
}
|
||||
|
||||
export interface SwapActivity {
|
||||
activity_details: SwapHistoryItem
|
||||
block_datetime: string
|
||||
activity_type: string
|
||||
}
|
||||
|
||||
export function isLiquidationActivityFeedItem(
|
||||
item: ActivityFeed,
|
||||
): item is LiquidationActivity {
|
||||
|
@ -312,6 +334,16 @@ export function isSpotTradeActivityFeedItem(
|
|||
return false
|
||||
}
|
||||
|
||||
export function isSwapActivityFeedItem(
|
||||
item: ActivityFeed,
|
||||
): item is SwapActivity {
|
||||
console.log(item)
|
||||
if (item.activity_type === 'swap') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export function isPerpLiquidation(
|
||||
activityDetails: SpotOrPerpLiquidationItem,
|
||||
): activityDetails is PerpLiquidationFeedItem {
|
||||
|
@ -321,22 +353,6 @@ export function isPerpLiquidation(
|
|||
return false
|
||||
}
|
||||
|
||||
export interface SwapHistoryItem {
|
||||
block_datetime: string
|
||||
mango_account: string
|
||||
signature: string
|
||||
swap_in_amount: number
|
||||
swap_in_loan: number
|
||||
swap_in_loan_origination_fee: number
|
||||
swap_in_price_usd: number
|
||||
swap_in_symbol: string
|
||||
swap_out_amount: number
|
||||
loan: number
|
||||
loan_origination_fee: number
|
||||
swap_out_price_usd: number
|
||||
swap_out_symbol: string
|
||||
}
|
||||
|
||||
export interface NFT {
|
||||
address: string
|
||||
collectionAddress?: string
|
||||
|
@ -375,7 +391,7 @@ export type GroupedDataItem = PerpStatsItem & Record<string, any>
|
|||
export type ActivityFeed = {
|
||||
activity_type: string
|
||||
block_datetime: string
|
||||
symbol: string
|
||||
symbol?: string
|
||||
activity_details:
|
||||
| DepositWithdrawFeedItem
|
||||
| SpotLiquidationFeedItem
|
||||
|
|
Loading…
Reference in New Issue