import React, { FunctionComponent, useEffect, useState } from 'react' import { ExclamationCircleIcon } from '@heroicons/react/outline' import Modal from './Modal' import Input, { Label } 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' import { useWallet } from '@solana/wallet-adapter-react' interface DepositModalProps { onClose: () => void isOpen: boolean repayAmount?: string tokenSymbol?: string } const DepositModal: FunctionComponent = ({ isOpen, onClose, repayAmount, tokenSymbol = '', }) => { const { t } = useTranslation('common') const { wallet } = useWallet() 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 if (!wallet) return setSubmitting(true) deposit({ amount: parseFloat(inputAmount), fromTokenAcc: selectedAccount.account, mangoAccount, wallet, }) .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(wallet) actions.fetchWalletTokens(wallet) }) }) .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 = repayAmount ? (parseFloat(inputAmount) / parseFloat(repayAmount)) * 100 : null const net = repayAmount ? parseFloat(inputAmount) - parseFloat(repayAmount) : null const repayMessage = percentage === 100 ? t('repay-full') : typeof percentage === 'number' && percentage > 100 ? t('repay-and-deposit', { amount: trimDecimals(net, 6).toString(), symbol: selectedAccount.config.symbol, }) : typeof percentage === 'number' ? 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} 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)