import { Transition } from '@headlessui/react' import { ChevronDownIcon, ChevronRightIcon, QuestionMarkCircleIcon, } from '@heroicons/react/20/solid' import { useTranslation } from 'next-i18next' import Image from 'next/legacy/image' import { Fragment, useEffect, useMemo, useState } from 'react' import { useViewport } from '../../hooks/useViewport' import { formatDecimal, formatFixedDecimals } from '../../utils/numbers' import { breakpoints } from '../../utils/theme' import { IconButton, LinkButton } from '../shared/Button' import ContentBox from '../shared/ContentBox' import Tooltip from '@components/shared/Tooltip' import { Bank } from '@blockworks-foundation/mango-v4' import { useRouter } from 'next/router' import useJupiterMints from 'hooks/useJupiterMints' import { Table, Td, Th, TrBody, TrHead } from '@components/shared/TableElements' import useMangoGroup from 'hooks/useMangoGroup' import dayjs from 'dayjs' import mangoStore, { TokenStatsItem } from '@store/mangoStore' import SheenLoader from '@components/shared/SheenLoader' import dynamic from 'next/dynamic' const DetailedAreaChart = dynamic( () => import('@components/shared/DetailedAreaChart'), { ssr: false } ) interface TotalValueItem { date: string borrowValue: number depositValue: number } const TokenStats = () => { const { t } = useTranslation(['common', 'token']) const actions = mangoStore((s) => s.actions) const tokenStats = mangoStore((s) => s.tokenStats.data) const initialStatsLoad = mangoStore((s) => s.tokenStats.initialLoad) const loadingStats = mangoStore((s) => s.tokenStats.loading) const [showTokenDetails, setShowTokenDetails] = useState('') const { group } = useMangoGroup() const { mangoTokens } = useJupiterMints() const { width } = useViewport() const showTableView = width ? width > breakpoints.md : false const router = useRouter() useEffect(() => { if (group && !initialStatsLoad) { actions.fetchTokenStats() } }, [group]) const totalValues = useMemo(() => { if (!tokenStats?.length) return [] const values: TotalValueItem[] = tokenStats.reduce( (a: TotalValueItem[], c: TokenStatsItem) => { const hasDate = a.find((d: TotalValueItem) => d.date === c.date_hour) if (!hasDate) { a.push({ date: c.date_hour, depositValue: Math.floor(c.total_deposits * c.price), borrowValue: Math.floor(c.total_borrows * c.price), }) } else { hasDate.depositValue = hasDate.depositValue + Math.floor(c.total_deposits * c.price) hasDate.borrowValue = hasDate.borrowValue + Math.floor(c.total_borrows * c.price) } return a }, [] ) return values.reverse() }, [tokenStats]) const banks = useMemo(() => { if (group) { const rawBanks = Array.from(group?.banksMapByName, ([key, value]) => ({ key, value, })) return rawBanks } return [] }, [group]) const handleShowTokenDetails = (name: string) => { showTokenDetails ? setShowTokenDetails('') : setShowTokenDetails(name) } const [totalDepositValue, totalBorrowValue] = useMemo(() => { if (banks.length) { return [ banks.reduce( (a, c) => a + c.value[0].uiPrice * c.value[0].uiDeposits(), 0 ), banks.reduce( (a, c) => a + c.value[0].uiPrice * c.value[0].uiBorrows(), 0 ), ] } return [0, 0] }, [banks]) const goToTokenPage = (bank: Bank) => { router.push(`/token/${bank.name}`, undefined, { shallow: true }) } return (
{loadingStats ? (
) : totalValues.length ? (
`$${x.toFixed(2)}`} title={t('total-deposit-value')} xKey="date" yKey={'depositValue'} />
) : null} {loadingStats ? (
) : totalValues.length ? (
`$${x.toFixed(2)}`} title={t('total-borrow-value')} xKey="date" yKey={'borrowValue'} />
) : null}
{showTableView ? ( {banks.map(({ key, value }) => { const bank = value[0] let logoURI if (mangoTokens?.length) { logoURI = mangoTokens.find( (t) => t.address === bank.mint.toString() )?.logoURI } return ( ) })}
{t('token')} {t('total-deposits')} {t('total-borrows')}
{t('rates')}
{t('utilization')}
{t('asset-weight')}
{t('liability-weight')}
{logoURI ? ( ) : ( )}

{bank.name}

{formatFixedDecimals(bank.uiDeposits())}

{formatFixedDecimals(bank.uiBorrows())}

{formatDecimal(bank.getDepositRateUi(), 2, { fixed: true, })} %

|

{formatDecimal(bank.getBorrowRateUi(), 2, { fixed: true, })} %

{bank.uiDeposits() > 0 ? formatDecimal( (bank.uiBorrows() / bank.uiDeposits()) * 100, 1, { fixed: true } ) : '0.0'} %

{bank.initAssetWeight.toFixed(2)}

{bank.initLiabWeight.toFixed(2)}

goToTokenPage(bank)} size="small" >
) : (
{banks.map(({ key, value }) => { const bank = value[0] let logoURI if (mangoTokens?.length) { logoURI = mangoTokens.find( (t) => t.address === bank.mint.toString() )?.logoURI } return (
{logoURI ? ( ) : ( )}

{bank.name}

{t('total-deposits')}

{formatFixedDecimals(bank.uiDeposits())}

{t('total-borrows')}

{formatFixedDecimals(bank.uiBorrows())}

handleShowTokenDetails(bank.name)} >

{t('rates')}

{formatDecimal(bank.getDepositRate().toNumber(), 2)}% | {formatDecimal(bank.getBorrowRate().toNumber(), 2)}%

{t('utilization')}

{bank.uiDeposits() > 0 ? formatDecimal( (bank.uiBorrows() / bank.uiDeposits()) * 100, 1, { fixed: true } ) : '0.0'} %

{t('asset-weight')}

{bank.initAssetWeight.toFixed(2)}

{t('liability-weight')}

{bank.initLiabWeight.toFixed(2)}

goToTokenPage(bank)} > {t('token:token-details')}
) })}
)} ) } export default TokenStats