mars-v2-frontend/src/components/Account/AccountSummary.tsx
Linkie Link 5a1d02393d
fix: added updatedAccount to AccountSummary (#414)
Co-authored-by: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com>
2023-09-01 11:08:57 +02:00

130 lines
4.6 KiB
TypeScript

import classNames from 'classnames'
import { HTMLAttributes, useMemo } from 'react'
import Accordion from 'components/Accordion'
import AccountBalancesTable from 'components/Account/AccountBalancesTable'
import AccountComposition from 'components/Account/AccountComposition'
import HealthBar from 'components/Account/HealthBar'
import Card from 'components/Card'
import DisplayCurrency from 'components/DisplayCurrency'
import { FormattedNumber } from 'components/FormattedNumber'
import Text from 'components/Text'
import { BN_ZERO } from 'constants/math'
import { ORACLE_DENOM } from 'constants/oracle'
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
import useHealthComputer from 'hooks/useHealthComputer'
import useIsOpenArray from 'hooks/useIsOpenArray'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
import usePrices from 'hooks/usePrices'
import useStore from 'store'
import { BNCoin } from 'types/classes/BNCoin'
import { calculateAccountBalanceValue, calculateAccountLeverage } from 'utils/accounts'
interface Props {
account: Account
}
export default function AccountSummary(props: Props) {
const [isOpen, toggleOpen] = useIsOpenArray(2, true)
const { data: prices } = usePrices()
const updatedAccount = useStore((s) => s.updatedAccount)
const accountBalance = useMemo(
() =>
props.account
? calculateAccountBalanceValue(updatedAccount ?? props.account, prices)
: BN_ZERO,
[props.account, updatedAccount, prices],
)
const { availableAssets: borrowAvailableAssets, accountBorrowedAssets } =
useBorrowMarketAssetsTableData()
const { availableAssets: lendingAvailableAssets, accountLentAssets } =
useLendingMarketAssetsTableData()
const borrowAssetsData = useMemo(
() => [...borrowAvailableAssets, ...accountBorrowedAssets],
[borrowAvailableAssets, accountBorrowedAssets],
)
const lendingAssetsData = useMemo(
() => [...lendingAvailableAssets, ...accountLentAssets],
[lendingAvailableAssets, accountLentAssets],
)
const { health } = useHealthComputer(props.account)
const { health: updatedHealth } = useHealthComputer(updatedAccount)
const leverage = useMemo(
() =>
props.account ? calculateAccountLeverage(updatedAccount ?? props.account, prices) : BN_ZERO,
[props.account, updatedAccount, prices],
)
if (!props.account) return null
return (
<div className='h-[546px] min-w-92.5 basis-92.5 max-w-screen overflow-y-scroll scrollbar-hide'>
<Card className='mb-4 h-min min-w-fit bg-white/10' contentClassName='flex'>
<Item label='Net worth' classes='flex-1'>
<DisplayCurrency
coin={BNCoin.fromDenomAndBigNumber(ORACLE_DENOM, accountBalance)}
className='text-sm'
/>
</Item>
<Item label='Leverage' classes='flex-1'>
<FormattedNumber
className='text-sm'
amount={leverage.toNumber()}
options={{ minDecimals: 2, suffix: 'x' }}
/>
</Item>
<Item label='Account health'>
<HealthBar health={health} updatedHealth={updatedHealth} className='w-[184px] h-1' />
</Item>
</Card>
<Accordion
items={[
{
title: `Credit Account ${props.account.id} Composition`,
renderContent: () =>
props.account ? <AccountComposition account={props.account} /> : null,
isOpen: isOpen[0],
toggleOpen: (index: number) => toggleOpen(index),
renderSubTitle: () => <></>,
},
{
title: 'Balances',
renderContent: () =>
props.account ? (
<AccountBalancesTable
account={updatedAccount ? updatedAccount : props.account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
/>
) : null,
isOpen: isOpen[1],
toggleOpen: (index: number) => toggleOpen(index),
renderSubTitle: () => <></>,
},
]}
allowMultipleOpen
/>
</div>
)
}
interface ItemProps extends HTMLAttributes<HTMLDivElement> {
label: string
classes?: string
}
function Item(props: ItemProps) {
return (
<div
className={classNames(
'flex flex-col justify-around px-3 py-1 border-r border-r-white/10',
props.classes,
)}
{...props}
>
<Text size='2xs' className='text-white/50 whitespace-nowrap'>
{props.label}
</Text>
<div className='flex h-4.5 w-full'>{props.children}</div>
</div>
)
}