import { Bank } from '@blockworks-foundation/mango-v4' import TabButtons from '@components/shared/TabButtons' import { useTranslation } from 'next-i18next' import { useMemo, useState } from 'react' import { TokenStatsItem } from 'types' import { formatYAxis } from 'utils/formatting' import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart' import TokenRatesChart from './TokenRatesChart' import Switch from '@components/forms/Switch' import { useTokenStats } from 'hooks/useTokenStats' const SWITCH_WRAPPER_CLASSES = 'mt-4 flex justify-end space-x-4 border-t border-th-bkg-3 px-4 py-2 md:px-6' interface GroupedTokenDataItem extends TokenStatsItem { intervalStartMillis: number } const groupTokenByHourlyInterval = ( data: TokenStatsItem[], daysToShow: string, dataKey: 'total_deposits' | 'total_borrows', ) => { let intervalDurationHours if (daysToShow === '30') { intervalDurationHours = 24 } else if (daysToShow === '7') { intervalDurationHours = 4 } else { intervalDurationHours = 1 } const intervalMillis = intervalDurationHours * 60 * 60 * 1000 const groupedData = [] let currentGroup: GroupedTokenDataItem | null = null for (let i = 0; i < data.length; i++) { const obj = data[i] const date = new Date(obj.date_hour) const intervalStartMillis = Math.floor(date.getTime() / intervalMillis) * intervalMillis if ( !currentGroup || currentGroup.intervalStartMillis !== intervalStartMillis ) { currentGroup = { ...obj, intervalStartMillis: intervalStartMillis, } groupedData.push(currentGroup) } else { currentGroup[dataKey] += obj[dataKey] } } return groupedData } const ChartTabs = ({ bank }: { bank: Bank }) => { const { t } = useTranslation('token') const [showDepositsRelativeChange, setShowDepositsRelativeChange] = useState(true) const [showDepositsNotional, setShowDepositsNotional] = useState(false) const [showBorrowsRelativeChange, setShowBorrowsRelativeChange] = useState(true) const [showBorrowsNotional, setShowBorrowsNotional] = useState(false) const [activeDepositsTab, setActiveDepositsTab] = useState( 'token:total-deposits', ) const [activeBorrowsTab, setActiveBorrowsTab] = useState( 'token:total-borrows', ) const [depositDaysToShow, setDepositDaysToShow] = useState('30') const [borrowDaysToShow, setBorrowDaysToShow] = useState('30') const [depositRateDaysToShow, setDepositRateDaysToShow] = useState('30') const [borrowRateDaysToShow, setBorrowRateDaysToShow] = useState('30') const { data: tokenStats, isLoading } = useTokenStats(bank.mint) const formattedStats = useMemo(() => { if (!tokenStats?.data?.length) return [] return tokenStats.data .filter((c) => c.token_index === bank.tokenIndex) .sort( (a, b) => new Date(a.date_hour).getTime() - new Date(b.date_hour).getTime(), ) }, [bank, tokenStats]) const depositsStats = useMemo(() => { if (!formattedStats.length) return [] if (showDepositsRelativeChange) { if (!showDepositsNotional) return formattedStats return formattedStats.map((currentStat) => { currentStat = { ...currentStat, total_deposits: currentStat.total_deposits * bank.uiPrice, } return currentStat }) } return formattedStats .map((currentStat, index, array) => { const previousStat = array[index - 1] if (previousStat) { const isNotionalMultiplier = showDepositsNotional ? bank.uiPrice : 1 currentStat = { ...currentStat, total_deposits: (currentStat.total_deposits - previousStat.total_deposits) * isNotionalMultiplier, } } return currentStat }) .slice(1) }, [bank, formattedStats, showDepositsNotional, showDepositsRelativeChange]) const borrowsStats = useMemo(() => { if (!formattedStats.length) return [] if (showBorrowsRelativeChange) { if (!showBorrowsNotional) return formattedStats return formattedStats.map((currentStat) => { currentStat = { ...currentStat, total_borrows: currentStat.total_borrows * bank.uiPrice, } return currentStat }) } return formattedStats .map((currentStat, index, array) => { const previousStat = array[index - 1] if (previousStat) { const isNotionalMultiplier = showBorrowsNotional ? bank.uiPrice : 1 currentStat = { ...currentStat, total_borrows: (currentStat.total_borrows - previousStat.total_borrows) * isNotionalMultiplier, } } return currentStat }) .slice(1) }, [bank, formattedStats, showBorrowsNotional, showBorrowsRelativeChange]) return (
setActiveDepositsTab(v)} showBorders values={[ ['token:total-deposits', 0], ['token:deposit-rates', 0], ]} />
{activeDepositsTab === 'token:total-deposits' ? ( <>
formatYAxis(x)} title={`${t('token:deposits')}`} xKey="date_hour" yKey={'total_deposits'} chartType={showDepositsRelativeChange ? 'area' : 'bar'} prefix={showDepositsNotional ? '$' : ''} />
setShowDepositsRelativeChange(!showDepositsRelativeChange) } small > {t('stats:show-relative')} setShowDepositsNotional(!showDepositsNotional) } small > {t('stats:notional')}
) : (
)}
setActiveBorrowsTab(v)} showBorders values={[ ['token:total-borrows', 0], ['token:borrow-rates', 0], ]} />
{activeBorrowsTab === 'token:total-borrows' ? ( <>
formatYAxis(x)} title={`${t('token:borrows')}`} xKey="date_hour" yKey={'total_borrows'} chartType={showBorrowsRelativeChange ? 'area' : 'bar'} prefix={showBorrowsNotional ? '$' : ''} />
setShowBorrowsRelativeChange(!showBorrowsRelativeChange) } small > {t('stats:show-relative')} setShowBorrowsNotional(!showBorrowsNotional) } small > {t('stats:notional')}
) : (
)}
) } export default ChartTabs