mars-v2-frontend/src/components/Account/AccountDetails/index.tsx
Linkie Link db1048bf4c
various fixes (#535)
* fix: fixed autoConnect

* tidy: Credit Account

* fix: fallback timer

* fix: clearTimer

* fix: fixed v1 links

* fix: changed the farm columns

* fix: updated doc urls according to Dino (#531)

* fix: updated doc urls according to Dino

* fix: updated the v1 url

* Build(deps-dev): bump @types/react from 18.2.23 to 18.2.27 (#530)

Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.23 to 18.2.27.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* 🐛stAtom chart data (#533)

* env: update

* env: tidy

* fix: fixed v1 links

* fix: no need for camelcase in keywords

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com>
2023-10-11 12:56:13 +02:00

184 lines
7.1 KiB
TypeScript

import classNames from 'classnames'
import { useCallback, useMemo } from 'react'
import AccountBalancesTable from 'components/Account/AccountBalancesTable'
import AccountComposition from 'components/Account/AccountComposition'
import AccountDetailsLeverage from 'components/Account/AccountDetails/AccountDetailsLeverage'
import Skeleton from 'components/Account/AccountDetails/Skeleton'
import EscButton from 'components/Button/EscButton'
import { glowElement } from 'components/Button/utils'
import Card from 'components/Card'
import DisplayCurrency from 'components/DisplayCurrency'
import { FormattedNumber } from 'components/FormattedNumber'
import { HealthGauge } from 'components/HealthGauge'
import { ThreeDots } from 'components/Icons'
import Text from 'components/Text'
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
import { REDUCE_MOTION_KEY } from 'constants/localStore'
import { ORACLE_DENOM } from 'constants/oracle'
import useAccountId from 'hooks/useAccountId'
import useAccounts from 'hooks/useAccounts'
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
import useCurrentAccount from 'hooks/useCurrentAccount'
import useHealthComputer from 'hooks/useHealthComputer'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
import useLocalStorage from 'hooks/useLocalStorage'
import usePrices from 'hooks/usePrices'
import useStore from 'store'
import { BNCoin } from 'types/classes/BNCoin'
import {
calculateAccountApr,
calculateAccountBalanceValue,
calculateAccountLeverage,
} from 'utils/accounts'
export default function AccountDetailsController() {
const address = useStore((s) => s.address)
const { isLoading } = useAccounts(address)
const accountId = useAccountId()
const account = useCurrentAccount()
const focusComponent = useStore((s) => s.focusComponent)
if (!address || focusComponent) return null
if ((isLoading && accountId && !focusComponent) || !account) return <Skeleton />
return <AccountDetails account={account} />
}
interface Props {
account: Account
}
function AccountDetails(props: Props) {
const { account } = props
const [reduceMotion] = useLocalStorage<boolean>(REDUCE_MOTION_KEY, DEFAULT_SETTINGS.reduceMotion)
const updatedAccount = useStore((s) => s.updatedAccount)
const accountDetailsExpanded = useStore((s) => s.accountDetailsExpanded)
const { health } = useHealthComputer(account)
const { health: updatedHealth } = useHealthComputer(updatedAccount || account)
const { data: prices } = usePrices()
const accountBalanceValue = useMemo(
() => calculateAccountBalanceValue(updatedAccount ?? account, prices),
[updatedAccount, account, prices],
)
const coin = BNCoin.fromDenomAndBigNumber(ORACLE_DENOM, accountBalanceValue)
const leverage = useMemo(() => calculateAccountLeverage(account, prices), [account, prices])
const updatedLeverage = useMemo(() => {
if (!updatedAccount) return null
const updatedLeverage = calculateAccountLeverage(updatedAccount, prices)
if (updatedLeverage.eq(leverage)) return null
return updatedLeverage
}, [updatedAccount, prices, leverage])
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 apr = useMemo(
() =>
calculateAccountApr(updatedAccount ?? account, borrowAssetsData, lendingAssetsData, prices),
[account, borrowAssetsData, lendingAssetsData, prices, updatedAccount],
)
function AccountDetailsHeader() {
const onClose = useCallback(() => useStore.setState({ accountDetailsExpanded: false }), [])
return (
<div className='flex items-center justify-between w-full p-4 bg-white/10 '>
<Text size='lg' className='flex items-center flex-grow font-semibold'>
{`Credit Account ${account.id}`}
</Text>
<EscButton onClick={onClose} hideText className='w-6 h-6' />
</div>
)
}
return (
<div
data-testid='account-details'
className={classNames(
accountDetailsExpanded ? 'right-6.5' : '-right-80',
'w-100 flex items-start gap-4 absolute top-6',
!reduceMotion && 'transition-all duration-300',
)}
>
<div
className={classNames(
'flex flex-wrap min-w-16 w-16 group relative',
'border rounded-base border-white/20',
'bg-white/5 backdrop-blur-sticky',
!reduceMotion && 'transition-colors duration-300',
'hover:bg-white/10 hover:cursor-pointer ',
)}
onClick={() => useStore.setState({ accountDetailsExpanded: !accountDetailsExpanded })}
>
<div className='flex flex-wrap justify-center w-full py-4'>
<HealthGauge health={health} updatedHealth={updatedHealth} />
<Text size='2xs' className='mb-0.5 mt-1 w-full text-center text-white/50'>
Health
</Text>
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50 whitespace-nowrap'>
Net worth
</Text>
<DisplayCurrency coin={coin} className='w-full text-center truncate text-2xs ' />
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50'>
Leverage
</Text>
<AccountDetailsLeverage
leverage={leverage.toNumber() || 1}
updatedLeverage={updatedLeverage?.toNumber() || null}
/>
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50'>
APR
</Text>
<FormattedNumber
className={'w-full text-center text-2xs'}
amount={apr.toNumber()}
options={{ maxDecimals: 2, minDecimals: 2, suffix: '%' }}
animate
/>
</div>
<div
className={classNames(
'flex justify-center items-center w-full h-6 opacity-50',
!reduceMotion && 'transition-[opacity] duration-300',
'absolute -bottom-6',
'group-hover:opacity-100',
)}
>
{!accountDetailsExpanded && <ThreeDots className='h-1' />}
</div>
{glowElement(!reduceMotion)}
</div>
<div className='flex w-90 backdrop-blur-sticky'>
<Card className='w-full bg-white/5' title={<AccountDetailsHeader />}>
<AccountComposition account={account} />
<Text className='w-full px-4 py-2 text-white bg-white/10'>Balances</Text>
<AccountBalancesTable
account={account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
/>
</Card>
</div>
</div>
)
}