Merge branch 'health-progress'
This commit is contained in:
commit
a6366e643e
|
@ -7,11 +7,7 @@ import {
|
|||
ZERO_I80F48,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import { useCallback, useState } from 'react'
|
||||
import {
|
||||
ExclamationIcon,
|
||||
ExternalLinkIcon,
|
||||
HeartIcon,
|
||||
} from '@heroicons/react/solid'
|
||||
import { ExclamationIcon, ExternalLinkIcon } from '@heroicons/react/solid'
|
||||
import { BellIcon } from '@heroicons/react/outline'
|
||||
import useMangoStore, { MNGO_INDEX } from '../stores/useMangoStore'
|
||||
import { abbreviateAddress, formatUsdValue, usdFormatter } from '../utils'
|
||||
|
@ -31,6 +27,7 @@ import Loading from './Loading'
|
|||
import CreateAlertModal from './CreateAlertModal'
|
||||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import { useRouter } from 'next/router'
|
||||
import HealthStatusCircle from './HealthStatusCircle'
|
||||
|
||||
const I80F48_100 = I80F48.fromString('100')
|
||||
|
||||
|
@ -131,11 +128,6 @@ export default function AccountInfo() {
|
|||
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Maint')
|
||||
: I80F48_100
|
||||
|
||||
const initHealthRatio =
|
||||
mangoAccount && mangoGroup && mangoCache
|
||||
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Init')
|
||||
: I80F48_100
|
||||
|
||||
const maintHealth =
|
||||
mangoAccount && mangoGroup && mangoCache
|
||||
? mangoAccount.getHealth(mangoGroup, mangoCache, 'Maint')
|
||||
|
@ -193,7 +185,7 @@ export default function AccountInfo() {
|
|||
) : null}
|
||||
<div>
|
||||
{mangoAccount ? (
|
||||
<div className="-mt-2 flex justify-center text-xs">
|
||||
<div className="-mt-2 mb-2 flex justify-center text-xs">
|
||||
<a
|
||||
className="flex items-center text-th-fgd-4 hover:text-th-primary"
|
||||
href={`https://explorer.solana.com/address/${mangoAccount?.publicKey}`}
|
||||
|
@ -208,12 +200,41 @@ export default function AccountInfo() {
|
|||
<div>
|
||||
<div className="flex justify-between pb-2">
|
||||
<div className="font-normal leading-4 text-th-fgd-3">
|
||||
{t('equity')}
|
||||
{t('value')}
|
||||
</div>
|
||||
<div className="text-th-fgd-1">
|
||||
{initialLoad ? <DataLoader /> : formatUsdValue(+equity)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between pb-2">
|
||||
<Tooltip
|
||||
content={
|
||||
<div>
|
||||
{t('tooltip-account-liquidated')}{' '}
|
||||
<a
|
||||
href="https://docs.mango.markets/mango/health-overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t('learn-more')}
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="default-transition cursor-help border-b border-dashed border-th-fgd-3 border-opacity-20 font-normal leading-4 text-th-fgd-3 hover:border-th-bkg-2">
|
||||
{t('health')}
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="flex items-center space-x-2">
|
||||
<HealthStatusCircle size={24} />
|
||||
<div className="text-th-fgd-1">
|
||||
{maintHealthRatio.gt(I80F48_100)
|
||||
? '>100'
|
||||
: maintHealthRatio.toFixed(2)}
|
||||
%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between pb-2">
|
||||
<div className="font-normal leading-4 text-th-fgd-3">
|
||||
{t('leverage')}
|
||||
|
@ -326,54 +347,7 @@ export default function AccountInfo() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-2 flex items-center rounded border border-th-bkg-4 p-2.5 sm:my-1">
|
||||
<div className="flex items-center pr-2">
|
||||
<HeartIcon
|
||||
className="mr-1.5 h-5 w-5 text-th-primary"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span>
|
||||
<Tooltip
|
||||
content={
|
||||
<div>
|
||||
{t('tooltip-account-liquidated')}{' '}
|
||||
<a
|
||||
href="https://docs.mango.markets/mango/health-overview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t('learn-more')}
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="default-transition cursor-help border-b border-dashed border-th-fgd-3 border-opacity-20 font-normal leading-4 text-th-fgd-3 hover:border-th-bkg-2">
|
||||
{t('health')}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex h-1.5 flex-grow rounded bg-th-bkg-4">
|
||||
<div
|
||||
style={{
|
||||
width: `${maintHealthRatio}%`,
|
||||
}}
|
||||
className={`flex rounded ${
|
||||
maintHealthRatio.toNumber() > 30
|
||||
? 'bg-th-green'
|
||||
: initHealthRatio.toNumber() > 0
|
||||
? 'bg-th-orange'
|
||||
: 'bg-th-red'
|
||||
}`}
|
||||
></div>
|
||||
</div>
|
||||
<div className="pl-2 text-right">
|
||||
{maintHealthRatio.gt(I80F48_100)
|
||||
? '>100'
|
||||
: maintHealthRatio.toFixed(2)}
|
||||
%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{mangoAccount && mangoAccount.beingLiquidated ? (
|
||||
<div className="flex items-center justify-center pt-0.5 text-xs">
|
||||
<ExclamationIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-th-red" />
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import { useMemo } from 'react'
|
||||
import { CircularProgressbar } from 'react-circular-progressbar'
|
||||
import useMangoStore from 'stores/useMangoStore'
|
||||
|
||||
const HealthStatusCircle = ({ size }: { size: number }) => {
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
||||
|
||||
const maintHealthRatio = useMemo(() => {
|
||||
return mangoAccount && mangoGroup && mangoCache
|
||||
? Number(mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Maint'))
|
||||
: 100
|
||||
}, [mangoAccount, mangoGroup, mangoCache])
|
||||
|
||||
const initHealthRatio = useMemo(() => {
|
||||
return mangoAccount && mangoGroup && mangoCache
|
||||
? Number(mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Init'))
|
||||
: 100
|
||||
}, [mangoAccount, mangoGroup, mangoCache])
|
||||
|
||||
return (
|
||||
<div style={{ width: size, height: size }}>
|
||||
<CircularProgressbar
|
||||
className={
|
||||
maintHealthRatio > 30
|
||||
? 'CircularProgressbar-green'
|
||||
: initHealthRatio > 0
|
||||
? 'CircularProgressbar-orange'
|
||||
: 'CircularProgressbar-red'
|
||||
}
|
||||
counterClockwise
|
||||
value={maintHealthRatio}
|
||||
strokeWidth={12}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HealthStatusCircle
|
|
@ -15,6 +15,9 @@ import LongShortChart from './LongShortChart'
|
|||
import Tooltip from 'components/Tooltip'
|
||||
import { CalendarIcon, InformationCircleIcon } from '@heroicons/react/outline'
|
||||
import { ZERO_BN } from '@blockworks-foundation/mango-client'
|
||||
import HealthStatusCircle from 'components/HealthStatusCircle'
|
||||
import { useViewport } from '../../hooks/useViewport'
|
||||
import { breakpoints } from '../TradePageGrid'
|
||||
|
||||
dayjs.extend(utc)
|
||||
|
||||
|
@ -59,6 +62,8 @@ export default function AccountOverview() {
|
|||
|
||||
const [pnl, setPnl] = useState(0)
|
||||
const [hourlyPerformanceStats, setHourlyPerformanceStats] = useState([])
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.sm : false
|
||||
|
||||
useEffect(() => {
|
||||
const pubKey = mangoAccount?.publicKey?.toString()
|
||||
|
@ -82,12 +87,6 @@ export default function AccountOverview() {
|
|||
: 100
|
||||
}, [mangoAccount, mangoGroup, mangoCache])
|
||||
|
||||
const initHealthRatio = useMemo(() => {
|
||||
return mangoAccount && mangoGroup && mangoCache
|
||||
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Init')
|
||||
: 100
|
||||
}, [mangoAccount, mangoGroup, mangoCache])
|
||||
|
||||
const mangoAccountValue = useMemo(() => {
|
||||
return mangoAccount && mangoGroup && mangoCache
|
||||
? +mangoAccount.computeValue(mangoGroup, mangoCache)
|
||||
|
@ -195,33 +194,22 @@ export default function AccountOverview() {
|
|||
{formatUsdValue(pnl)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-12 border-th-bkg-4 px-3 pt-3 sm:px-4 sm:pt-4 md:col-span-6 xl:col-span-3 xl:border-t">
|
||||
<div className="pb-0.5 text-xs text-th-fgd-3 sm:text-sm">
|
||||
{t('health-ratio')}
|
||||
</div>
|
||||
<div className={`text-xl font-bold text-th-fgd-1 sm:text-3xl`}>
|
||||
{maintHealthRatio < 100 ? maintHealthRatio.toFixed(2) : '>100'}%
|
||||
</div>
|
||||
{mangoAccount.beingLiquidated ? (
|
||||
<div className="flex items-center pt-0.5 text-xs sm:pt-2 sm:text-sm">
|
||||
<ExclamationIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-th-red sm:h-7 sm:w-7" />
|
||||
<span className="text-th-red">{t('being-liquidated')}</span>
|
||||
<div className="col-span-12 flex items-center justify-between border-b border-th-bkg-4 p-3 sm:p-4 md:col-span-6 xl:col-span-3 xl:border-t">
|
||||
<div>
|
||||
<div className="pb-0.5 text-xs text-th-fgd-3 sm:text-sm">
|
||||
{t('health-ratio')}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="-mx-3 mt-3 flex h-1 rounded bg-th-bkg-3 sm:-mx-4 sm:mt-4">
|
||||
<div
|
||||
style={{
|
||||
width: `${maintHealthRatio}%`,
|
||||
}}
|
||||
className={`flex rounded ${
|
||||
maintHealthRatio > 30
|
||||
? 'bg-th-green'
|
||||
: initHealthRatio > 0
|
||||
? 'bg-th-orange'
|
||||
: 'bg-th-red'
|
||||
}`}
|
||||
></div>
|
||||
<div className={`text-xl font-bold text-th-fgd-1 sm:text-3xl`}>
|
||||
{maintHealthRatio < 100 ? maintHealthRatio.toFixed(2) : '>100'}%
|
||||
</div>
|
||||
{mangoAccount.beingLiquidated ? (
|
||||
<div className="flex items-center pt-0.5 text-xs sm:pt-2 sm:text-sm">
|
||||
<ExclamationIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-th-red sm:h-7 sm:w-7" />
|
||||
<span className="text-th-red">{t('being-liquidated')}</span>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<HealthStatusCircle size={isMobile ? 32 : 48} />
|
||||
</div>
|
||||
<div className="col-span-12 border-b border-th-bkg-4 p-3 sm:p-4 md:col-span-6 xl:col-span-3 xl:border-t">
|
||||
<div className="pb-0.5 text-xs text-th-fgd-3 sm:text-sm">
|
||||
|
@ -249,14 +237,14 @@ export default function AccountOverview() {
|
|||
</div>
|
||||
</div>
|
||||
<div className="my-8">
|
||||
<h2 className="mb-4">{t('portfolio-balance')}</h2>
|
||||
<h2 className="mb-4">{t('account-exposure')}</h2>
|
||||
<div className="grid grid-flow-col grid-cols-1 grid-rows-2 md:grid-cols-2 md:grid-rows-1 md:gap-6">
|
||||
<div className="border-t border-th-bkg-4 p-3 sm:p-4 md:border-b">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<Tooltip content={t('total-long-tooltip')}>
|
||||
<div className="flex items-center space-x-1.5 pb-0.5">
|
||||
<div className="text-th-fgd-3">{t('total-long')}</div>
|
||||
<div className="text-th-fgd-3">{t('long')}</div>
|
||||
<InformationCircleIcon className="h-5 w-5 text-th-fgd-3" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
@ -274,7 +262,7 @@ export default function AccountOverview() {
|
|||
<div>
|
||||
<Tooltip content={t('total-short-tooltip')}>
|
||||
<div className="flex items-center space-x-1.5 pb-0.5">
|
||||
<div className="text-th-fgd-3">{t('total-short')}</div>
|
||||
<div className="text-th-fgd-3">{t('short')}</div>
|
||||
<InformationCircleIcon className="h-5 w-5 text-th-fgd-3" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
"next-themes": "^0.1.1",
|
||||
"rc-slider": "^9.7.5",
|
||||
"react": "^17.0.2",
|
||||
"react-circular-progressbar": "^2.0.4",
|
||||
"react-cool-dimensions": "^2.0.7",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-grid-layout": "^1.3.3",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"account-details-tip-title": "Account Details",
|
||||
"account-equity": "Account Equity",
|
||||
"account-equity-chart-title": "Account Equity",
|
||||
"account-exposure": "Account Exposure",
|
||||
"account-health": "Account Health",
|
||||
"account-health-tip-desc": "To avoid liquidation you must keep your account health above 0%. To increase the health of your account, reduce borrows or deposit funds.",
|
||||
"account-health-tip-title": "Account Health",
|
||||
|
@ -212,7 +213,7 @@
|
|||
"liquidations": "Liquidations",
|
||||
"liquidity": "Liquidity",
|
||||
"liquidity-mining": "Liquidity Mining",
|
||||
"long": "long",
|
||||
"long": "Long",
|
||||
"low": "Low",
|
||||
"maint-health": "Maint Health",
|
||||
"make-trade": "Make a trade",
|
||||
|
@ -362,7 +363,7 @@
|
|||
"settle-all": "Settle All",
|
||||
"settle-error": "Error settling funds",
|
||||
"settle-success": "Successfully settled funds",
|
||||
"short": "short",
|
||||
"short": "Short",
|
||||
"show-all": "Show all in Nav",
|
||||
"show-less": "Show less",
|
||||
"show-more": "Show More",
|
||||
|
@ -430,10 +431,8 @@
|
|||
"total-funding": "Total Funding",
|
||||
"total-funding-stats": "Total Funding Earned/Paid",
|
||||
"total-liabilities": "Total Liabilities Value",
|
||||
"total-long": "Long Exposure",
|
||||
"total-long-tooltip": "Deposits, long futures positions and positive pnl unsettled positions",
|
||||
"total-pnl": "Total PnL",
|
||||
"total-short": "Short Exposure",
|
||||
"total-short-tooltip": "Borrows, short futures positions and negative pnl unsettled positions",
|
||||
"total-srm": "Total SRM in Mango",
|
||||
"totals": "Totals",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"account-details-tip-title": "Detalles de la cuenta",
|
||||
"account-equity": "Patrimonio de la cuenta",
|
||||
"account-equity-chart-title": "Patrimonio de la cuenta",
|
||||
"account-exposure": "Account Exposure",
|
||||
"account-health": "Estado de la cuenta",
|
||||
"account-health-tip-desc": "Para evitar la liquidación, debe mantener el estado de su cuenta por encima del 0%. Para mejorar el estado de su cuenta, reduzca los préstamos o los fondos de depósito.",
|
||||
"account-health-tip-title": "Estado de la cuenta",
|
||||
|
@ -430,10 +431,8 @@
|
|||
"total-funding": "Financiamiento total",
|
||||
"total-funding-stats": "Financiamiento total ganado / pagado",
|
||||
"total-liabilities": "Valor del pasivo total",
|
||||
"total-long": "Long Exposure",
|
||||
"total-long-tooltip": "Deposits, long futures positions and positive pnl unsettled positions",
|
||||
"total-pnl": "Total PnL",
|
||||
"total-short": "Short Exposure",
|
||||
"total-short-tooltip": "Borrows, short futures positions and negative pnl unsettled positions",
|
||||
"total-srm": "SRM total en mango",
|
||||
"totals": "Totales",
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
{
|
||||
"about-to-withdraw": "您正在取款",
|
||||
"above": "高于",
|
||||
|
@ -9,6 +11,7 @@
|
|||
"account-details-tip-title": "帐户细节",
|
||||
"account-equity": "帐户余额",
|
||||
"account-equity-chart-title": "帐户余额",
|
||||
"account-exposure": "Account Exposure",
|
||||
"account-health": "帐户健康",
|
||||
"account-health-tip-desc": "为了避免被清算,您必须将帐户健康度保持在0%以上。为了提高健康度,请减少借贷或存入资产。",
|
||||
"account-health-tip-title": "帐户健康",
|
||||
|
@ -430,10 +433,8 @@
|
|||
"total-funding": "资金费总数量",
|
||||
"total-funding-stats": "资金费收/付统计",
|
||||
"total-liabilities": "总债务价值",
|
||||
"total-long": "Long Exposure",
|
||||
"total-long-tooltip": "Deposits, long futures positions and positive pnl unsettled positions",
|
||||
"total-pnl": "总盈亏",
|
||||
"total-short": "Short Exposure",
|
||||
"total-short-tooltip": "Borrows, short futures positions and negative pnl unsettled positions",
|
||||
"total-srm": "在Mango裡的SRM总量",
|
||||
"totals": "总量",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"account-details-tip-title": "帳戶細節",
|
||||
"account-equity": "帳戶餘額",
|
||||
"account-equity-chart-title": "帳戶餘額",
|
||||
"account-exposure": "Account Exposure",
|
||||
"account-health": "帳戶健康",
|
||||
"account-health-tip-desc": "為了避免被清算,您必須將帳戶健康度保持在0%以上。為了提高健康度,請減少借貸或存入資產。",
|
||||
"account-health-tip-title": "帳戶健康",
|
||||
|
@ -430,10 +431,8 @@
|
|||
"total-funding": "資金費總數量",
|
||||
"total-funding-stats": "資金費收/付統計",
|
||||
"total-liabilities": "總債務價值",
|
||||
"total-long": "Long Exposure",
|
||||
"total-long-tooltip": "Deposits, long futures positions and positive pnl unsettled positions",
|
||||
"total-pnl": "總盈虧",
|
||||
"total-short": "Short Exposure",
|
||||
"total-short-tooltip": "Borrows, short futures positions and negative pnl unsettled positions",
|
||||
"total-srm": "在Mango裡的SRM總量",
|
||||
"totals": "總量",
|
||||
|
|
|
@ -528,3 +528,55 @@ body::-webkit-scrollbar-corner {
|
|||
.react-horizontal-scrolling-menu--item {
|
||||
@apply w-full;
|
||||
}
|
||||
|
||||
/*
|
||||
* react-circular-progressbar styles
|
||||
* All of the styles in this file are configurable!
|
||||
*/
|
||||
|
||||
.CircularProgressbar {
|
||||
/*
|
||||
* This fixes an issue where the CircularProgressbar svg has
|
||||
* 0 width inside a "display: flex" container, and thus not visible.
|
||||
*/
|
||||
width: 100%;
|
||||
/*
|
||||
* This fixes a centering issue with CircularProgressbarWithChildren:
|
||||
* https://github.com/kevinsqi/react-circular-progressbar/issues/94
|
||||
*/
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.CircularProgressbar .CircularProgressbar-path {
|
||||
@apply stroke-th-primary;
|
||||
stroke-linecap: round;
|
||||
transition: stroke-dashoffset 0.5s ease 0s;
|
||||
}
|
||||
|
||||
.CircularProgressbar .CircularProgressbar-trail {
|
||||
@apply stroke-th-bkg-4;
|
||||
/* Used when trail is not full diameter, i.e. when props.circleRatio is set */
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
.CircularProgressbar .CircularProgressbar-text {
|
||||
@apply fill-th-fgd-3 text-sm;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
.CircularProgressbar .CircularProgressbar-background {
|
||||
@apply fill-th-bkg-4;
|
||||
}
|
||||
|
||||
.CircularProgressbar.CircularProgressbar-green .CircularProgressbar-path {
|
||||
@apply stroke-th-green;
|
||||
}
|
||||
|
||||
.CircularProgressbar.CircularProgressbar-orange .CircularProgressbar-path {
|
||||
@apply stroke-th-orange;
|
||||
}
|
||||
|
||||
.CircularProgressbar.CircularProgressbar-red .CircularProgressbar-path {
|
||||
@apply stroke-th-red;
|
||||
}
|
||||
|
|
|
@ -5555,6 +5555,11 @@ rc-util@^5.16.1, rc-util@^5.19.2, rc-util@^5.3.0:
|
|||
react-is "^16.12.0"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
react-circular-progressbar@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-circular-progressbar/-/react-circular-progressbar-2.0.4.tgz#5b04a9cf6be8c522c180e4e99ec6db63677335b0"
|
||||
integrity sha512-OfX0ThSxRYEVGaQSt0DlXfyl5w4DbXHsXetyeivmoQrh9xA9bzVPHNf8aAhOIiwiaxX2WYWpLDB3gcpsDJ9oww==
|
||||
|
||||
react-cool-dimensions@^2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-cool-dimensions/-/react-cool-dimensions-2.0.7.tgz#2fe6657608f034cd7c89f149ed14e79cf1cb2d50"
|
||||
|
|
Loading…
Reference in New Issue