import React, { FunctionComponent, useEffect, useState } from 'react' import { ExclamationCircleIcon } from '@heroicons/react/outline' import Modal from './Modal' import Input from './Input' import AccountSelect from './AccountSelect' import { ElementTitle } from './styles' import useMangoStore from '../stores/useMangoStore' import Loading from './Loading' import Button from './Button' import InlineNotification from './InlineNotification' import { deposit } from '../utils/mango' import { notify } from '../utils/notifications' import { sleep, trimDecimals } from '../utils' import { useTranslation } from 'next-i18next' import ButtonGroup from './ButtonGroup' interface DepositModalProps { onClose: () => void isOpen: boolean repayAmount?: string tokenSymbol?: string } const DepositModal: FunctionComponent = ({ isOpen, onClose, repayAmount, tokenSymbol = '', }) => { const { t } = useTranslation('common') const [inputAmount, setInputAmount] = useState(repayAmount || '') const [submitting, setSubmitting] = useState(false) const [invalidAmountMessage, setInvalidAmountMessage] = useState('') const [depositPercentage, setDepositPercentage] = useState('') const walletTokens = useMangoStore((s) => s.wallet.tokens) const actions = useMangoStore((s) => s.actions) const [selectedAccount, setSelectedAccount] = useState(walletTokens[0]) const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) useEffect(() => { if (tokenSymbol) { const symbolAccount = walletTokens.find( (a) => a.config.symbol === tokenSymbol ) if (symbolAccount) { setSelectedAccount(symbolAccount) } else { setSelectedAccount(null) } } }, [tokenSymbol, walletTokens]) const handleAccountSelect = (account) => { setInputAmount('') setDepositPercentage('') setInvalidAmountMessage('') setSelectedAccount(account) } const handleDeposit = () => { const mangoAccount = useMangoStore.getState().selectedMangoAccount.current setSubmitting(true) deposit({ amount: parseFloat(inputAmount), fromTokenAcc: selectedAccount.account, mangoAccount, }) .then((response) => { notify({ title: t('deposit-successful'), type: 'success', txid: response instanceof Array ? response[1] : response, }) setSubmitting(false) onClose() sleep(500).then(() => { mangoAccount ? actions.reloadMangoAccount() : actions.fetchAllMangoAccounts() actions.fetchWalletTokens() }) }) .catch((err) => { notify({ title: t('deposit-failed'), description: err.message, txid: err?.txid, type: 'error', }) onClose() }) } const validateAmountInput = (amount) => { if (Number(amount) <= 0) { setInvalidAmountMessage(t('enter-amount')) } if (selectedAccount && Number(amount) > selectedAccount.uiBalance) { setInvalidAmountMessage(t('insufficient-balance-deposit')) } } const onChangeAmountInput = (amount) => { setInputAmount(amount) if (!selectedAccount) { setInvalidAmountMessage(t('supported-assets')) return } setDepositPercentage('') setInvalidAmountMessage('') } const onChangeAmountButtons = async (percentage) => { setDepositPercentage(percentage) if (!selectedAccount) { setInvalidAmountMessage(t('supported-assets')) return } const max = selectedAccount.uiBalance const amount = ((parseInt(percentage) / 100) * max).toString() if (percentage === '100') { setInputAmount(amount) } else { setInputAmount(trimDecimals(amount, 6).toString()) } setInvalidAmountMessage('') validateAmountInput(amount) } const percentage = (parseFloat(inputAmount) / parseFloat(repayAmount)) * 100 const net = parseFloat(inputAmount) - parseFloat(repayAmount) const repayMessage = percentage === 100 ? t('repay-full') : percentage > 100 ? t('repay-and-deposit', { amount: trimDecimals(net, 6).toString(), symbol: selectedAccount.config.symbol, }) : t('repay-partial', { percentage: percentage.toFixed(2), }) const inputDisabled = selectedAccount && selectedAccount.config.symbol === 'SOL' && selectedAccount.uiBalance.toString() === inputAmount return ( {t('deposit-funds')} {!mangoAccount ? (
{t('first-deposit-desc')}
) : null} {tokenSymbol && !selectedAccount ? (
) : null} {repayAmount && selectedAccount?.uiBalance < parseFloat(repayAmount) ? (
) : null}
{t('amount')}
validateAmountInput(e.target.value)} value={inputAmount || ''} onChange={(e) => onChangeAmountInput(e.target.value)} suffix={selectedAccount?.config.symbol} />
{invalidAmountMessage ? (
{invalidAmountMessage}
) : null}
onChangeAmountButtons(v)} unit="%" values={['25', '50', '75', '100']} />
{selectedAccount?.config.symbol === 'SOL' && parseFloat(inputAmount) > selectedAccount?.uiBalance - 0.01 ? (
{t('you-must-leave-enough-sol')}
) : null} {repayAmount ? (
) : null}
{!repayAmount ? (
) : null}
) } export default React.memo(DepositModal)