mango-ui-v3/components/AccountsModal.tsx

207 lines
7.0 KiB
TypeScript
Raw Normal View History

import React, { FunctionComponent, useEffect, useState } from 'react'
import { RadioGroup } from '@headlessui/react'
import { CheckCircleIcon } from '@heroicons/react/solid'
import { PlusCircleIcon } from '@heroicons/react/outline'
import useMangoStore from '../stores/useMangoStore'
2021-07-07 13:38:04 -07:00
import {
MangoAccount,
MangoCache,
MangoGroup,
2021-07-27 09:22:50 -07:00
// ZERO_I80F48,
2021-07-07 13:38:04 -07:00
} from '@blockworks-foundation/mango-client'
import { abbreviateAddress, formatUsdValue } from '../utils'
import useLocalStorageState from '../hooks/useLocalStorageState'
import Modal from './Modal'
import { ElementTitle } from './styles'
import Button, { LinkButton } from './Button'
import NewAccount from './NewAccount'
export const LAST_ACCOUNT_KEY = 'lastAccountViewed-3.0'
interface AccountsModalProps {
onClose: () => void
isOpen: boolean
}
const AccountsModal: FunctionComponent<AccountsModalProps> = ({
isOpen,
onClose,
}) => {
const [showNewAccountForm, setShowNewAccountForm] = useState(false)
const [newAccPublicKey, setNewAccPublicKey] = useState(null)
2021-06-23 08:32:33 -07:00
const mangoAccounts = useMangoStore((s) => s.mangoAccounts)
const selectedMangoAccount = useMangoStore(
(s) => s.selectedMangoAccount.current
)
2021-07-06 21:34:21 -07:00
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
const setMangoStore = useMangoStore((s) => s.set)
2021-08-16 10:59:44 -07:00
const actions = useMangoStore((s) => s.actions)
const [, setLastAccountViewed] = useLocalStorageState(LAST_ACCOUNT_KEY)
2021-06-23 08:32:33 -07:00
const handleMangoAccountChange = (mangoAccount: MangoAccount) => {
setLastAccountViewed(mangoAccount.publicKey.toString())
setMangoStore((state) => {
2021-06-23 08:32:33 -07:00
state.selectedMangoAccount.current = mangoAccount
})
2021-08-01 05:48:15 -07:00
2021-08-16 10:59:44 -07:00
actions.fetchTradeHistory()
2021-08-01 05:48:15 -07:00
onClose()
}
useEffect(() => {
if (newAccPublicKey) {
setMangoStore((state) => {
2021-08-18 18:05:16 -07:00
state.selectedMangoAccount.current = mangoAccounts.find(
(ma) => ma.publicKey.toString() === newAccPublicKey
)
})
}
2021-06-23 08:32:33 -07:00
}, [mangoAccounts, newAccPublicKey])
const handleNewAccountCreation = (newAccPublicKey) => {
if (newAccPublicKey) {
setNewAccPublicKey(newAccPublicKey)
}
setShowNewAccountForm(false)
}
const handleShowNewAccountForm = () => {
setNewAccPublicKey(null)
setShowNewAccountForm(true)
}
return (
2021-08-16 10:59:44 -07:00
<Modal isOpen={isOpen} onClose={onClose}>
2021-06-23 08:32:33 -07:00
{mangoAccounts.length > 0 ? (
!showNewAccountForm ? (
<>
<Modal.Header>
2021-07-29 12:05:16 -07:00
<ElementTitle noMarignBottom>Mango Accounts</ElementTitle>
</Modal.Header>
<div className="flex items-center justify-between pb-3 text-th-fgd-1">
<div className="font-semibold">
2021-06-23 08:32:33 -07:00
{mangoAccounts.length > 1
? 'Select an account'
: 'Your Account'}
</div>
<Button
className="text-xs flex items-center justify-center pt-0 pb-0 h-8 pl-3 pr-3"
onClick={() => handleShowNewAccountForm()}
>
<div className="flex items-center">
<PlusCircleIcon className="h-5 w-5 mr-1.5" />
New
</div>
</Button>
</div>
<RadioGroup
2021-06-23 08:32:33 -07:00
value={selectedMangoAccount}
onChange={(acc) => handleMangoAccountChange(acc)}
>
<RadioGroup.Label className="sr-only">
2021-07-29 12:05:16 -07:00
Select a Mango Account
</RadioGroup.Label>
<div className="space-y-2">
2021-06-23 08:32:33 -07:00
{mangoAccounts.map((account) => (
<RadioGroup.Option
key={account.publicKey.toString()}
value={account}
className={({ checked }) =>
`${
checked
? 'bg-th-bkg-3 ring-1 ring-th-green ring-inset'
: 'bg-th-bkg-1'
}
relative rounded-md w-full px-3 py-3 cursor-pointer default-transition flex hover:bg-th-bkg-3 focus:outline-none`
}
>
{({ checked }) => (
<>
<div className="flex items-center justify-between w-full">
<div className="flex items-center">
<div className="text-sm">
<RadioGroup.Label className="cursor-pointer flex items-center text-th-fgd-1">
<div>
<div className="pb-0.5">
2021-07-30 13:37:00 -07:00
{account?.name ||
2021-07-29 12:05:16 -07:00
abbreviateAddress(account.publicKey)}
</div>
2021-07-06 21:34:21 -07:00
{mangoGroup ? (
<div className="text-th-fgd-3 text-xs">
<AccountInfo
2021-07-06 21:34:21 -07:00
mangoGroup={mangoGroup}
mangoAccount={account}
mangoCache={mangoCache}
/>
</div>
) : null}
</div>
</RadioGroup.Label>
</div>
</div>
{checked && (
<div className="flex-shrink-0 text-th-green">
<CheckCircleIcon className="w-5 h-5" />
</div>
)}
</div>
</>
)}
</RadioGroup.Option>
))}
</div>
</RadioGroup>
</>
) : (
<>
<NewAccount onAccountCreation={handleNewAccountCreation} />
<LinkButton
className="flex justify-center mt-4 text-th-fgd-3 w-full"
onClick={() => setShowNewAccountForm(false)}
>
Cancel
</LinkButton>
</>
)
) : (
<NewAccount onAccountCreation={handleNewAccountCreation} />
)}
</Modal>
)
}
2021-07-07 13:38:04 -07:00
const AccountInfo = ({
mangoGroup,
mangoAccount,
mangoCache,
}: {
mangoGroup: MangoGroup
mangoAccount: MangoAccount
mangoCache: MangoCache
}) => {
const accountEquity = mangoAccount.computeValue(mangoGroup, mangoCache)
const leverage = mangoAccount.getLeverage(mangoGroup, mangoCache).toFixed(2)
return (
<div className="text-th-fgd-3 text-xs">
{formatUsdValue(accountEquity)}
<span className="px-1.5 text-th-fgd-4">|</span>
<span
className={
parseFloat(leverage) > 4
? 'text-th-red'
: parseFloat(leverage) > 2
? 'text-th-orange'
: 'text-th-green'
}
>
{leverage}x
</span>
</div>
)
}
export default React.memo(AccountsModal)