import HealthContributionsChart from './HealthContributionsChart' import useMangoGroup from 'hooks/useMangoGroup' import useMangoAccount from 'hooks/useMangoAccount' import { useMemo, useState } from 'react' import { HealthType } from '@blockworks-foundation/mango-v4' import { ArrowLeftIcon, QuestionMarkCircleIcon, } from '@heroicons/react/20/solid' import Tooltip from '@components/shared/Tooltip' import TokenLogo from '@components/shared/TokenLogo' import { useTranslation } from 'next-i18next' import MarketLogos from '@components/trade/MarketLogos' import mangoStore from '@store/mangoStore' import TokensHealthTable from './TokensHealthTable' import MarketsHealthTable from './MarketsHealthTable' export interface HealthContribution { asset: string contribution: number isAsset: boolean } const HealthContributions = ({ hideView }: { hideView: () => void }) => { const { t } = useTranslation(['common', 'account', 'trade']) const { group } = useMangoGroup() const { mangoAccount } = useMangoAccount() const [initActiveIndex, setInitActiveIndex] = useState( undefined ) const [maintActiveIndex, setMaintActiveIndex] = useState( undefined ) const [initHealthContributions, maintHealthContributions] = useMemo(() => { if (!group || !mangoAccount) return [[], []] const init = mangoAccount .getHealthContributionPerAssetUi(group, HealthType.init) .map((item) => ({ ...item, contribution: Math.abs(item.contribution), isAsset: item.contribution > 0 ? true : false, })) const maint = mangoAccount .getHealthContributionPerAssetUi(group, HealthType.maint) .map((item) => ({ ...item, contribution: Math.abs(item.contribution), isAsset: item.contribution > 0 ? true : false, })) return [init, maint] }, [group, mangoAccount]) const [initHealthMarkets, initHealthTokens] = useMemo(() => { if (!initHealthContributions.length) return [[], []] const splitData = initHealthContributions.reduce( ( acc: { market: HealthContribution[]; token: HealthContribution[] }, obj: HealthContribution ) => { if (obj.asset.includes('/')) { acc.market.push(obj) } else { acc.token.push(obj) } return acc }, { market: [], token: [] } ) return [splitData.market, splitData.token] }, [initHealthContributions]) const [maintHealthMarkets, maintHealthTokens] = useMemo(() => { if (!maintHealthContributions.length) return [[], []] const splitData = maintHealthContributions.reduce( ( acc: { market: HealthContribution[]; token: HealthContribution[] }, obj: HealthContribution ) => { if (obj.asset.includes('/')) { acc.market.push(obj) } else { acc.token.push(obj) } return acc }, { market: [], token: [] } ) const markets = splitData.market.filter((d) => d.contribution > 0) const tokens = splitData.token return [markets, tokens] }, [maintHealthContributions]) const handleLegendClick = (item: HealthContribution) => { const maintIndex = maintChartData.findIndex((d) => d.asset === item.asset) const initIndex = initChartData.findIndex((d) => d.asset === item.asset) setMaintActiveIndex(maintIndex) setInitActiveIndex(initIndex) } const handleLegendMouseEnter = (item: HealthContribution) => { const maintIndex = maintChartData.findIndex((d) => d.asset === item.asset) const initIndex = initChartData.findIndex((d) => d.asset === item.asset) setMaintActiveIndex(maintIndex) setInitActiveIndex(initIndex) } const handleLegendMouseLeave = () => { setInitActiveIndex(undefined) setMaintActiveIndex(undefined) } const renderLegendLogo = (asset: string) => { const group = mangoStore.getState().group if (!group) return const isSpotMarket = asset.includes('/') if (isSpotMarket) { const market = group.getSerum3MarketByName(asset) return market ? ( ) : ( ) } else { const bank = group.banksMapByName.get(asset)?.[0] return bank ? (
) : ( ) } } const initChartData = useMemo(() => { if (!initHealthContributions.length) return [] return initHealthContributions .filter((cont) => { if (cont.asset.includes('/')) { return cont.contribution > 0.01 } else return cont }) .sort((a, b) => { const aMultiplier = a.isAsset ? 1 : -1 const bMultiplier = b.isAsset ? 1 : -1 return b.contribution * bMultiplier - a.contribution * aMultiplier }) }, [initHealthContributions]) const maintChartData = useMemo(() => { if (!maintHealthContributions.length) return [] return maintHealthContributions .filter((cont) => { if (cont.asset.includes('/')) { return cont.contribution > 0.01 } else return cont }) .sort((a, b) => { const aMultiplier = a.isAsset ? 1 : -1 const bMultiplier = b.isAsset ? 1 : -1 return b.contribution * bMultiplier - a.contribution * aMultiplier }) }, [maintHealthContributions]) return group && mangoAccount ? ( <>

{t('account:health-contributions')}

{t('account:init-health-contributions')}

{t('account:maint-health-contributions')}

{[...maintChartData] .sort((a, b) => b.contribution - a.contribution) .map((d, i) => { return (
handleLegendClick(d)} onMouseEnter={() => handleLegendMouseEnter(d)} onMouseLeave={handleLegendMouseLeave} > {renderLegendLogo(d.asset)} {d.asset}
) })}
{maintHealthTokens.length ? (

{t('tokens')}

) : null} {maintHealthMarkets.length ? (

{t('markets')}

) : null} ) : null } export default HealthContributions