mango-v4-ui/components/account/CreateAccountForm.tsx

151 lines
4.5 KiB
TypeScript
Raw Normal View History

2022-11-17 20:43:23 -08:00
import { ChangeEvent, useState } from 'react'
2022-10-07 04:47:15 -07:00
import { useTranslation } from 'next-i18next'
import mangoStore from '@store/mangoStore'
import { notify } from '../../utils/notifications'
import Button, { IconButton } from '../shared/Button'
import BounceLoader from '../shared/BounceLoader'
import Input from '../forms/Input'
import Label from '../forms/Label'
import { useWallet } from '@solana/wallet-adapter-react'
import InlineNotification from '../shared/InlineNotification'
import { MangoAccount } from '@blockworks-foundation/mango-v4'
import { ArrowLeftIcon } from '@heroicons/react/20/solid'
2022-11-16 17:53:33 -08:00
import useSolBalance from 'hooks/useSolBalance'
2023-02-27 23:20:11 -08:00
import { isMangoError } from 'types'
2022-10-07 04:47:15 -07:00
const getNextAccountNumber = (accounts: MangoAccount[]): number => {
if (accounts.length > 1) {
return (
accounts
.map((a) => a.accountNum)
.reduce((a, b) => Math.max(a, b), -Infinity) + 1
)
} else if (accounts.length === 1) {
return accounts[0].accountNum + 1
}
return 0
}
const CreateAccountForm = ({
isFirstAccount,
customClose,
handleBack,
}: {
isFirstAccount?: boolean
customClose?: () => void
handleBack?: () => void
}) => {
const { t } = useTranslation('common')
const [loading, setLoading] = useState(false)
const [name, setName] = useState('')
const { wallet } = useWallet()
2022-11-17 20:43:23 -08:00
const { maxSolDeposit } = useSolBalance()
2022-10-07 04:47:15 -07:00
const handleNewAccount = async () => {
const client = mangoStore.getState().client
const group = mangoStore.getState().group
2022-10-25 19:39:11 -07:00
const mangoAccounts = mangoStore.getState().mangoAccounts
2022-10-07 04:47:15 -07:00
const set = mangoStore.getState().set
if (!group || !wallet) return
setLoading(true)
try {
const newAccountNum = getNextAccountNumber(mangoAccounts)
const { signature: tx } = await client.createMangoAccount(
2022-10-07 04:47:15 -07:00
group,
newAccountNum,
2022-10-29 18:46:56 -07:00
name || `Account ${newAccountNum + 1}`,
2023-08-11 03:08:07 -07:00
10, // tokenCount
2022-10-07 04:47:15 -07:00
)
if (tx) {
2023-01-02 14:21:56 -08:00
const pk = wallet.adapter.publicKey
2022-10-25 19:39:11 -07:00
const mangoAccounts = await client.getMangoAccountsForOwner(group, pk!)
2022-11-15 09:10:44 -08:00
const reloadedMangoAccounts = await Promise.all(
2023-07-21 11:47:53 -07:00
mangoAccounts.map((ma) => ma.reloadSerum3OpenOrders(client)),
2022-11-15 09:10:44 -08:00
)
2022-10-07 04:47:15 -07:00
const newAccount = mangoAccounts.find(
2023-07-21 11:47:53 -07:00
(acc) => acc.accountNum === newAccountNum,
2022-10-07 04:47:15 -07:00
)
2022-10-31 09:39:43 -07:00
if (newAccount) {
set((s) => {
s.mangoAccount.current = newAccount
2022-11-15 09:10:44 -08:00
s.mangoAccounts = reloadedMangoAccounts
2022-10-31 09:39:43 -07:00
})
}
2022-10-07 04:47:15 -07:00
setLoading(false)
notify({
title: t('new-account-success'),
type: 'success',
txid: tx,
})
if (customClose) {
customClose()
}
}
2023-02-27 23:20:11 -08:00
} catch (e) {
console.error(e)
2022-10-07 04:47:15 -07:00
setLoading(false)
2023-02-27 23:20:11 -08:00
if (!isMangoError(e)) return
2022-10-07 04:47:15 -07:00
notify({
title: t('new-account-failed'),
2022-12-02 15:47:08 -08:00
txid: e?.txid,
2022-10-07 04:47:15 -07:00
type: 'error',
})
}
}
return loading ? (
<div className="flex h-full flex-col items-center justify-between">
<BounceLoader loadingMessage={t('creating-account')} />
</div>
) : (
<div className="flex h-full flex-col justify-between">
<div className="pb-4">
<div className="flex items-center">
{handleBack ? (
<IconButton className="mr-3" onClick={handleBack} size="small">
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
) : null}
2022-12-04 15:34:17 -08:00
<h2 className="w-full text-center">{t('create-account')}</h2>
{handleBack ? <div className="h-5 w-5" /> : null}
2022-10-07 04:47:15 -07:00
</div>
{isFirstAccount ? (
2023-05-23 21:41:04 -07:00
<p className="mt-1 text-center">
You need a Mango Account to get started.
</p>
2022-10-07 04:47:15 -07:00
) : null}
<div className="pt-4">
<Label optional text={t('account-name')} />
</div>
<Input
type="text"
name="name"
id="name"
placeholder="Account"
value={name}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setName(e.target.value)
}
2023-01-25 01:19:12 -08:00
maxLength={30}
2022-10-07 04:47:15 -07:00
/>
</div>
<div className="space-y-4">
2022-10-07 04:47:15 -07:00
<InlineNotification type="info" desc={t('insufficient-sol')} />
<Button
className="w-full"
2022-11-17 20:43:23 -08:00
disabled={maxSolDeposit <= 0}
onClick={handleNewAccount}
size="large"
>
2022-10-07 04:47:15 -07:00
{t('create-account')}
</Button>
2022-11-17 20:43:23 -08:00
{maxSolDeposit <= 0 ? (
<InlineNotification type="error" desc={t('deposit-more-sol')} />
) : null}
2022-10-07 04:47:15 -07:00
</div>
</div>
)
}
export default CreateAccountForm