mango-ui-v2/components/MarginBalances.tsx

239 lines
8.0 KiB
TypeScript
Raw Normal View History

2021-04-09 17:01:00 -07:00
import { useCallback, useState } from 'react'
2021-04-16 11:16:31 -07:00
import {
ExternalLinkIcon,
InformationCircleIcon,
} from '@heroicons/react/outline'
2021-04-09 07:27:49 -07:00
import FloatingElement from './FloatingElement'
2021-04-10 12:21:02 -07:00
import { ElementTitle } from './styles'
2021-04-09 07:27:49 -07:00
import useMangoStore from '../stores/useMangoStore'
import useMarketList from '../hooks/useMarketList'
import { floorToDecimal, tokenPrecision } from '../utils/index'
2021-04-09 17:01:00 -07:00
import DepositModal from './DepositModal'
2021-04-10 14:12:15 -07:00
import WithdrawModal from './WithdrawModal'
2021-04-10 12:21:02 -07:00
import Button from './Button'
2021-04-16 11:16:31 -07:00
import Tooltip from './Tooltip'
2021-04-25 22:20:05 -07:00
import MarginAccountSelect from './MarginAccountSelect'
import { MarginAccount } from '@blockworks-foundation/mango-client'
2021-04-09 07:27:49 -07:00
2021-04-14 23:16:36 -07:00
export default function MarginBalances() {
2021-04-25 22:20:05 -07:00
const setMangoStore = useMangoStore((s) => s.set)
const marginAccounts = useMangoStore((s) => s.marginAccounts)
2021-04-09 07:27:49 -07:00
const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
const selectedMarginAccount = useMangoStore(
(s) => s.selectedMarginAccount.current
)
const loadingMarginAccount = useMangoStore(
(s) => s.selectedMarginAccount.initialLoad
)
2021-04-10 12:21:02 -07:00
const connected = useMangoStore((s) => s.wallet.connected)
2021-04-09 07:27:49 -07:00
const { symbols } = useMarketList()
const [showDepositModal, setShowDepositModal] = useState(false)
const [showWithdrawModal, setShowWithdrawModal] = useState(false)
2021-04-09 17:01:00 -07:00
const handleCloseDeposit = useCallback(() => {
setShowDepositModal(false)
}, [])
2021-04-09 07:27:49 -07:00
2021-04-09 17:01:00 -07:00
const handleCloseWithdraw = useCallback(() => {
setShowWithdrawModal(false)
}, [])
2021-04-09 07:27:49 -07:00
2021-04-25 22:20:05 -07:00
const handleMarginAccountChange = (marginAccount: MarginAccount) => {
setMangoStore((state) => {
state.selectedMarginAccount.current = marginAccount
})
}
2021-04-09 07:27:49 -07:00
return (
<>
<FloatingElement>
<ElementTitle>
Margin Account
2021-04-16 11:16:31 -07:00
<Tooltip
2021-04-09 07:27:49 -07:00
content={
<AddressTooltip
owner={selectedMarginAccount?.owner.toString()}
marginAccount={selectedMarginAccount?.publicKey.toString()}
/>
}
2021-04-16 11:16:31 -07:00
>
<div>
<InformationCircleIcon
className={`h-5 w-5 ml-2 text-th-primary cursor-help`}
/>
</div>
</Tooltip>
2021-04-09 07:27:49 -07:00
</ElementTitle>
2021-04-25 22:20:05 -07:00
<div>
{marginAccounts.length > 1 ? (
<MarginAccountSelect
onChange={handleMarginAccountChange}
className="mb-2"
/>
) : null}
</div>
2021-04-09 07:27:49 -07:00
{selectedMangoGroup ? (
<table className={`min-w-full`}>
2021-04-09 07:27:49 -07:00
<thead>
2021-04-26 05:53:27 -07:00
<tr className={`text-center text-th-fgd-4 mb-2 text-xs`}>
<th scope="col" className={`flex-auto font-normal text-left`}>
2021-04-09 07:27:49 -07:00
Assets
</th>
2021-04-26 05:53:27 -07:00
<th
scope="col"
className={`flex-auto font-normal text-right px-2`}
>
2021-04-09 07:27:49 -07:00
Deposits
</th>
2021-04-26 05:53:27 -07:00
<th
scope="col"
className={`flex-auto font-normal text-right px-2`}
>
2021-04-09 07:27:49 -07:00
Borrows
</th>
2021-04-29 15:14:19 -07:00
<th
scope="col"
className="flex-auto font-normal flex justify-end items-center"
>
<Tooltip content="Deposit APR and Borrow APY">
<div>Deposits / Borrows</div>
</Tooltip>
2021-04-09 07:27:49 -07:00
</th>
</tr>
</thead>
<tbody>
{Object.entries(symbols).map(([name], i) => (
2021-04-16 04:50:56 -07:00
<tr key={name} className={`text-th-fgd-1`}>
<td className={`flex items-center py-2`}>
2021-04-09 07:27:49 -07:00
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${name.toLowerCase()}.svg`}
2021-04-16 04:50:56 -07:00
className={`mr-2.5`}
2021-04-09 07:27:49 -07:00
/>
<span>{name}</span>
</td>
2021-04-26 05:53:27 -07:00
<td className={`text-right px-2`}>
2021-04-09 07:27:49 -07:00
{selectedMarginAccount
? floorToDecimal(
selectedMarginAccount.getUiDeposit(
selectedMangoGroup,
i
),
tokenPrecision[name]
).toFixed(tokenPrecision[name])
2021-04-09 07:27:49 -07:00
: (0).toFixed(tokenPrecision[name])}
</td>
2021-04-26 05:53:27 -07:00
<td className={`text-right px-2`}>
2021-04-09 07:27:49 -07:00
{selectedMarginAccount
? selectedMarginAccount
2021-04-14 11:40:28 -07:00
.getUiBorrow(selectedMangoGroup, i)
2021-04-09 07:27:49 -07:00
.toFixed(tokenPrecision[name])
: (0).toFixed(tokenPrecision[name])}
</td>
2021-04-26 05:53:27 -07:00
<td className={`text-right`}>
<span className={`text-th-green`}>
2021-04-29 15:14:19 -07:00
{(selectedMangoGroup.getDepositRate(i) * 100).toFixed(2)}%
2021-04-09 07:27:49 -07:00
</span>
2021-04-13 07:10:57 -07:00
<span className={`text-th-fgd-4`}>{' / '}</span>
<span className={`text-th-red`}>
2021-04-29 15:14:19 -07:00
{(selectedMangoGroup.getBorrowRate(i) * 100).toFixed(2)}%
2021-04-09 07:27:49 -07:00
</span>
</td>
</tr>
))}
</tbody>
</table>
) : null}
2021-04-13 07:10:57 -07:00
<div className={`flex justify-center items-center mt-4`}>
<Button
onClick={() => setShowDepositModal(true)}
className="w-1/2"
disabled={!connected || loadingMarginAccount}
2021-04-13 07:10:57 -07:00
>
<span>Deposit</span>
</Button>
<Button
onClick={() => setShowWithdrawModal(true)}
className="ml-4 w-1/2"
disabled={
!connected || !selectedMarginAccount || loadingMarginAccount
}
2021-04-13 07:10:57 -07:00
>
<span>Withdraw</span>
</Button>
2021-04-09 07:27:49 -07:00
</div>
2021-04-19 09:15:49 -07:00
<div className={`text-center mt-4 text-th-fgd-4 text-sm`}>
2021-04-09 07:27:49 -07:00
Settle funds in the Balances tab
</div>
</FloatingElement>
{showDepositModal && (
2021-04-09 17:01:00 -07:00
<DepositModal isOpen={showDepositModal} onClose={handleCloseDeposit} />
2021-04-09 07:27:49 -07:00
)}
{showWithdrawModal && (
2021-04-10 14:12:15 -07:00
<WithdrawModal
2021-04-09 07:27:49 -07:00
isOpen={showWithdrawModal}
2021-04-09 17:01:00 -07:00
onClose={handleCloseWithdraw}
2021-04-09 07:27:49 -07:00
/>
)}
</>
)
}
2021-04-16 11:16:31 -07:00
const AddressTooltip = ({
owner,
marginAccount,
}: {
owner?: string
marginAccount?: string
}) => {
return (
<>
{owner && marginAccount ? (
<>
<div className={`flex flex-nowrap text-th-fgd-3`}>
2021-04-16 11:16:31 -07:00
Margin Account:
<a
className="text-th-fgd-1 default-transition hover:text-th-primary"
2021-04-16 11:16:31 -07:00
href={'https://explorer.solana.com/address/' + marginAccount}
target="_blank"
rel="noopener noreferrer"
>
<div className={`ml-2 flex items-center`}>
<span className={`underline`}>
{marginAccount.toString().substr(0, 5) +
'...' +
marginAccount.toString().substr(-5)}
2021-04-16 11:16:31 -07:00
</span>
<ExternalLinkIcon className={`h-4 w-4 ml-1`} />
2021-04-16 11:16:31 -07:00
</div>
</a>
</div>
<div className={`flex flex-nowrap text-th-fgd-3 pt-2`}>
2021-04-16 11:16:31 -07:00
Account Owner:
<a
className="text-th-fgd-1 default-transition hover:text-th-primary"
2021-04-16 11:16:31 -07:00
href={'https://explorer.solana.com/address/' + owner}
target="_blank"
rel="noopener noreferrer"
>
<div className={`ml-2 flex items-center`}>
<span className={`underline`}>
{owner.toString().substr(0, 5) +
'...' +
owner.toString().substr(-5)}
2021-04-16 11:16:31 -07:00
</span>
<ExternalLinkIcon className={`h-4 w-4 ml-1`} />
2021-04-16 11:16:31 -07:00
</div>
</a>
</div>
</>
) : (
'Connect a wallet and deposit funds to start trading'
)}
</>
)
}