add buttongroup and interest info to deposit/withdraw (#59)
This commit is contained in:
parent
da10aa9966
commit
ce2e32ee1a
|
@ -1,19 +1,18 @@
|
|||
import React, { FunctionComponent, useEffect, useState } from 'react'
|
||||
import { ExclamationCircleIcon } from '@heroicons/react/outline'
|
||||
import { ChevronLeftIcon } from '@heroicons/react/solid'
|
||||
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, { LinkButton } from './Button'
|
||||
import Slider from './Slider'
|
||||
import Button from './Button'
|
||||
import InlineNotification from './InlineNotification'
|
||||
import { deposit } from '../utils/mango'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { sleep } from '../utils'
|
||||
import { sleep, trimDecimals } from '../utils'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import ButtonGroup from './ButtonGroup'
|
||||
|
||||
interface DepositModalProps {
|
||||
onClose: () => void
|
||||
|
@ -31,10 +30,8 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
|
|||
const { t } = useTranslation('common')
|
||||
const [inputAmount, setInputAmount] = useState<string>(settleDeficit || '')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [showConfirm, setShowConfirm] = useState(false)
|
||||
const [invalidAmountMessage, setInvalidAmountMessage] = useState('')
|
||||
const [sliderPercentage, setSliderPercentage] = useState(0)
|
||||
const [maxButtonTransition, setMaxButtonTransition] = useState(false)
|
||||
const [depositPercentage, setDepositPercentage] = useState('')
|
||||
const walletTokens = useMangoStore((s) => s.wallet.tokens)
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const [selectedAccount, setSelectedAccount] = useState(walletTokens[0])
|
||||
|
@ -55,18 +52,11 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
|
|||
|
||||
const handleAccountSelect = (account) => {
|
||||
setInputAmount('')
|
||||
setSliderPercentage(0)
|
||||
setDepositPercentage('')
|
||||
setInvalidAmountMessage('')
|
||||
setSelectedAccount(account)
|
||||
}
|
||||
|
||||
const setMaxForSelectedAccount = () => {
|
||||
setInputAmount(selectedAccount.uiBalance.toString())
|
||||
setSliderPercentage(100)
|
||||
setInvalidAmountMessage('')
|
||||
setMaxButtonTransition(true)
|
||||
}
|
||||
|
||||
const handleDeposit = () => {
|
||||
const mangoAccount = useMangoStore.getState().selectedMangoAccount.current
|
||||
|
||||
|
@ -117,13 +107,12 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
|
|||
return
|
||||
}
|
||||
|
||||
const max = selectedAccount.uiBalance
|
||||
setSliderPercentage((amount / max) * 100)
|
||||
setDepositPercentage('')
|
||||
setInvalidAmountMessage('')
|
||||
}
|
||||
|
||||
const onChangeSlider = async (percentage) => {
|
||||
setSliderPercentage(percentage)
|
||||
const onChangeAmountButtons = async (percentage) => {
|
||||
setDepositPercentage(percentage)
|
||||
|
||||
if (!selectedAccount) {
|
||||
setInvalidAmountMessage(t('supported-assets'))
|
||||
|
@ -131,146 +120,99 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
|
|||
}
|
||||
|
||||
const max = selectedAccount.uiBalance
|
||||
const amount = (percentage / 100) * max
|
||||
if (percentage === 100) {
|
||||
setInputAmount(amount.toString())
|
||||
const amount = ((parseInt(percentage) / 100) * max).toString()
|
||||
if (percentage === '100') {
|
||||
setInputAmount(amount)
|
||||
} else {
|
||||
setInputAmount(amount.toString())
|
||||
setInputAmount(trimDecimals(amount, 6).toString())
|
||||
}
|
||||
setInvalidAmountMessage('')
|
||||
validateAmountInput(amount)
|
||||
}
|
||||
|
||||
// turn off slider transition for dragging slider handle interaction
|
||||
useEffect(() => {
|
||||
if (maxButtonTransition) {
|
||||
setMaxButtonTransition(false)
|
||||
}
|
||||
}, [maxButtonTransition])
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
{!showConfirm ? (
|
||||
<>
|
||||
<Modal.Header>
|
||||
<ElementTitle noMarignBottom>{t('deposit-funds')}</ElementTitle>
|
||||
</Modal.Header>
|
||||
{tokenSymbol && !selectedAccount ? (
|
||||
<InlineNotification
|
||||
desc={t('deposit-help', { tokenSymbol: tokenSymbol })}
|
||||
title={t('no-address', { tokenSymbol: tokenSymbol })}
|
||||
type="error"
|
||||
/>
|
||||
) : null}
|
||||
{settleDeficit ? (
|
||||
<InlineNotification
|
||||
desc={t('deposit-before', {
|
||||
settleDeficit: settleDeficit,
|
||||
tokenSymbol: tokenSymbol,
|
||||
})}
|
||||
title={t('not-enough-balance')}
|
||||
type="error"
|
||||
/>
|
||||
) : null}
|
||||
<AccountSelect
|
||||
accounts={walletTokens}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={handleAccountSelect}
|
||||
<Modal.Header>
|
||||
<ElementTitle noMarignBottom>{t('deposit-funds')}</ElementTitle>
|
||||
</Modal.Header>
|
||||
{tokenSymbol && !selectedAccount ? (
|
||||
<div className="mb-4">
|
||||
<InlineNotification
|
||||
desc={t('deposit-help', { tokenSymbol: tokenSymbol })}
|
||||
title={t('no-address', { tokenSymbol: tokenSymbol })}
|
||||
type="error"
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>{t('amount')}</div>
|
||||
<div
|
||||
className="text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline"
|
||||
onClick={setMaxForSelectedAccount}
|
||||
>
|
||||
{t('max')}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{settleDeficit ? (
|
||||
<div className="mb-4">
|
||||
<InlineNotification
|
||||
desc={t('deposit-before', {
|
||||
settleDeficit: settleDeficit,
|
||||
tokenSymbol: tokenSymbol,
|
||||
})}
|
||||
title={t('not-enough-balance')}
|
||||
type="error"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<AccountSelect
|
||||
accounts={walletTokens}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={handleAccountSelect}
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>{t('amount')}</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
className={`border border-th-fgd-4 flex-grow pr-11`}
|
||||
placeholder="0.00"
|
||||
error={!!invalidAmountMessage}
|
||||
onBlur={(e) => validateAmountInput(e.target.value)}
|
||||
value={inputAmount || ''}
|
||||
onChange={(e) => onChangeAmountInput(e.target.value)}
|
||||
suffix={selectedAccount?.config.symbol}
|
||||
/>
|
||||
</div>
|
||||
{invalidAmountMessage ? (
|
||||
<div className="flex items-center pt-1.5 text-th-red">
|
||||
<ExclamationCircleIcon className="h-4 w-4 mr-1.5" />
|
||||
{invalidAmountMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="pt-1">
|
||||
<ButtonGroup
|
||||
activeValue={depositPercentage}
|
||||
onChange={(v) => onChangeAmountButtons(v)}
|
||||
unit="%"
|
||||
values={['25', '50', '75', '100']}
|
||||
/>
|
||||
</div>
|
||||
<div className={`pt-6 flex justify-center`}>
|
||||
<Button
|
||||
onClick={handleDeposit}
|
||||
className="w-full"
|
||||
disabled={submitting}
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
{submitting && <Loading className="-ml-1 mr-3" />}
|
||||
{t('deposit')}
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
className={`border border-th-fgd-4 flex-grow pr-11`}
|
||||
placeholder="0.00"
|
||||
error={!!invalidAmountMessage}
|
||||
onBlur={(e) => validateAmountInput(e.target.value)}
|
||||
value={inputAmount}
|
||||
onChange={(e) => onChangeAmountInput(e.target.value)}
|
||||
suffix={selectedAccount?.config.symbol}
|
||||
/>
|
||||
</div>
|
||||
{invalidAmountMessage ? (
|
||||
<div className="flex items-center pt-1.5 text-th-red">
|
||||
<ExclamationCircleIcon className="h-4 w-4 mr-1.5" />
|
||||
{invalidAmountMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="pt-3 pb-4">
|
||||
<Slider
|
||||
disabled={null}
|
||||
value={sliderPercentage}
|
||||
onChange={(v) => onChangeSlider(v)}
|
||||
step={1}
|
||||
maxButtonTransition={maxButtonTransition}
|
||||
/>
|
||||
</div>
|
||||
<div className={`pt-8 flex justify-center`}>
|
||||
<Button
|
||||
onClick={() => setShowConfirm(true)}
|
||||
className="w-full"
|
||||
disabled={
|
||||
!inputAmount ||
|
||||
parseFloat(inputAmount) <= 0 ||
|
||||
!selectedAccount ||
|
||||
parseFloat(inputAmount) > selectedAccount.uiBalance
|
||||
}
|
||||
>
|
||||
{t('next')}
|
||||
</Button>
|
||||
</div>
|
||||
{!mangoAccount ? (
|
||||
<div className="flex text-th-fgd-4 text-xxs mt-1">
|
||||
<div className="mx-auto">{t('insufficient-sol')}</div>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Modal.Header>
|
||||
<ElementTitle noMarignBottom>{t('confirm-deposit')}</ElementTitle>
|
||||
</Modal.Header>
|
||||
<div className="bg-th-bkg-1 p-4 rounded-lg text-th-fgd-1 text-center">
|
||||
<div className="text-th-fgd-3 pb-1">{t('depositing')}</div>
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="font-semibold relative text-xl">
|
||||
{inputAmount}
|
||||
<span className="absolute bottom-0.5 font-normal ml-1.5 text-xs text-th-fgd-4">
|
||||
{selectedAccount?.config.symbol}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`mt-5 flex justify-center`}>
|
||||
<Button
|
||||
onClick={handleDeposit}
|
||||
className="w-full"
|
||||
disabled={submitting}
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
{submitting && <Loading className="-ml-1 mr-3" />}
|
||||
{t('deposit')}
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
<LinkButton
|
||||
className="flex items-center mt-4 text-th-fgd-3"
|
||||
onClick={() => setShowConfirm(false)}
|
||||
>
|
||||
<ChevronLeftIcon className="h-5 w-5 mr-1" />
|
||||
{t('back')}
|
||||
</LinkButton>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
{!settleDeficit ? (
|
||||
<div className="pt-3">
|
||||
<InlineNotification desc={t('interest-info')} type="info" />
|
||||
</div>
|
||||
) : null}
|
||||
{!mangoAccount ? (
|
||||
<div className="flex text-th-fgd-4 text-xxs mt-1">
|
||||
<div className="mx-auto">{t('insufficient-sol')}</div>
|
||||
</div>
|
||||
) : null}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
CheckCircleIcon,
|
||||
ExclamationCircleIcon,
|
||||
ExclamationIcon,
|
||||
InformationCircleIcon,
|
||||
} from '@heroicons/react/outline'
|
||||
|
||||
interface InlineNotificationProps {
|
||||
|
@ -22,8 +23,10 @@ const InlineNotification: FunctionComponent<InlineNotificationProps> = ({
|
|||
? 'border-th-red'
|
||||
: type === 'success'
|
||||
? 'border-th-green'
|
||||
: type === 'info'
|
||||
? 'border-th-bkg-4'
|
||||
: 'border-th-orange'
|
||||
} flex items-center mb-4 p-2.5 rounded-md`}
|
||||
} flex items-center p-2 rounded-md`}
|
||||
>
|
||||
{type === 'error' ? (
|
||||
<ExclamationCircleIcon className="flex-shrink-0 h-5 w-5 mr-2 text-th-red" />
|
||||
|
@ -34,9 +37,18 @@ const InlineNotification: FunctionComponent<InlineNotificationProps> = ({
|
|||
{type === 'warning' ? (
|
||||
<ExclamationIcon className="flex-shrink-0 h-5 w-5 mr-2 text-th-orange" />
|
||||
) : null}
|
||||
{type === 'info' ? (
|
||||
<InformationCircleIcon className="flex-shrink-0 h-5 w-5 mr-2 text-th-fgd-3" />
|
||||
) : null}
|
||||
<div>
|
||||
<div className="pb-1 text-th-fgd-1">{title}</div>
|
||||
<div className="font-normal text-th-fgd-3 text-xs">{desc}</div>
|
||||
<div className="text-th-fgd-3">{title}</div>
|
||||
<div
|
||||
className={`${
|
||||
title && desc && 'pt-1'
|
||||
} font-normal text-xs text-th-fgd-3`}
|
||||
>
|
||||
{desc}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { FunctionComponent, useEffect, useState } from 'react'
|
||||
import React, { FunctionComponent, useState } from 'react'
|
||||
import {
|
||||
ExclamationCircleIcon,
|
||||
InformationCircleIcon,
|
||||
|
@ -14,11 +14,12 @@ import {
|
|||
} from '../utils/index'
|
||||
import Loading from './Loading'
|
||||
import Button from './Button'
|
||||
import Slider from './Slider'
|
||||
import Tooltip from './Tooltip'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { deposit } from '../utils/mango'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import ButtonGroup from './ButtonGroup'
|
||||
import InlineNotification from './InlineNotification'
|
||||
|
||||
interface NewAccountProps {
|
||||
onAccountCreation?: (x?) => void
|
||||
|
@ -28,11 +29,10 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
onAccountCreation,
|
||||
}) => {
|
||||
const { t } = useTranslation('common')
|
||||
const [inputAmount, setInputAmount] = useState(null)
|
||||
const [inputAmount, setInputAmount] = useState<string>('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [invalidAmountMessage, setInvalidAmountMessage] = useState('')
|
||||
const [sliderPercentage, setSliderPercentage] = useState(0)
|
||||
const [maxButtonTransition, setMaxButtonTransition] = useState(false)
|
||||
const [depositPercentage, setDepositPercentage] = useState('')
|
||||
const [invalidNameMessage, setInvalidNameMessage] = useState('')
|
||||
const [name, setName] = useState('')
|
||||
const walletTokens = useMangoStore((s) => s.wallet.tokens)
|
||||
|
@ -45,24 +45,16 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
)
|
||||
|
||||
const handleAccountSelect = (account) => {
|
||||
setInputAmount(0)
|
||||
setSliderPercentage(0)
|
||||
setInputAmount('')
|
||||
setDepositPercentage('')
|
||||
setInvalidAmountMessage('')
|
||||
setSelectedAccount(account)
|
||||
}
|
||||
|
||||
const setMaxForSelectedAccount = () => {
|
||||
const max = selectedAccount.uiBalance
|
||||
setInputAmount(max)
|
||||
setSliderPercentage(100)
|
||||
setInvalidAmountMessage('')
|
||||
setMaxButtonTransition(true)
|
||||
}
|
||||
|
||||
const handleNewAccountDeposit = () => {
|
||||
setSubmitting(true)
|
||||
deposit({
|
||||
amount: inputAmount,
|
||||
amount: parseFloat(inputAmount),
|
||||
fromTokenAcc: selectedAccount.account,
|
||||
accountName: name,
|
||||
})
|
||||
|
@ -97,21 +89,26 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
}
|
||||
|
||||
const onChangeAmountInput = (amount) => {
|
||||
const max = selectedAccount.uiBalance
|
||||
setInputAmount(amount)
|
||||
setSliderPercentage((amount / max) * 100)
|
||||
setDepositPercentage('')
|
||||
setInvalidAmountMessage('')
|
||||
}
|
||||
|
||||
const onChangeSlider = async (percentage) => {
|
||||
const onChangeAmountButtons = async (percentage) => {
|
||||
setDepositPercentage(percentage)
|
||||
|
||||
if (!selectedAccount) {
|
||||
setInvalidAmountMessage(t('supported-assets'))
|
||||
return
|
||||
}
|
||||
|
||||
const max = selectedAccount.uiBalance
|
||||
const amount = (percentage / 100) * max
|
||||
if (percentage === 100) {
|
||||
const amount = ((parseInt(percentage) / 100) * max).toString()
|
||||
if (percentage === '100') {
|
||||
setInputAmount(amount)
|
||||
} else {
|
||||
setInputAmount(trimDecimals(amount, 6))
|
||||
setInputAmount(trimDecimals(amount, 6).toString())
|
||||
}
|
||||
setSliderPercentage(percentage)
|
||||
setInvalidAmountMessage('')
|
||||
validateAmountInput(amount)
|
||||
}
|
||||
|
@ -129,17 +126,13 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
}
|
||||
}
|
||||
|
||||
// turn off slider transition for dragging slider handle interaction
|
||||
useEffect(() => {
|
||||
if (maxButtonTransition) {
|
||||
setMaxButtonTransition(false)
|
||||
}
|
||||
}, [maxButtonTransition])
|
||||
|
||||
return (
|
||||
<>
|
||||
<ElementTitle className="pb-2">Create Account</ElementTitle>
|
||||
<div className="pb-4">
|
||||
<ElementTitle>Create Account</ElementTitle>
|
||||
<div className="mx-auto pb-4 text-center text-th-fgd-3 text-xs">
|
||||
{t('insufficient-sol')}
|
||||
</div>
|
||||
<div className="border-b border-th-bkg-4 mb-4 pb-6">
|
||||
<div className="flex items-center pb-2 text-th-fgd-1">
|
||||
{t('account-name')}{' '}
|
||||
<span className="ml-1 text-th-fgd-3">{t('optional')}</span>
|
||||
|
@ -163,20 +156,15 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="font-bold pb-2 text-center text-th-fgd-2">
|
||||
{t('initial-deposit')}
|
||||
</div>
|
||||
<AccountSelect
|
||||
accounts={walletTokens}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={handleAccountSelect}
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>{t('amount')}</div>
|
||||
<div
|
||||
className="text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline"
|
||||
onClick={setMaxForSelectedAccount}
|
||||
>
|
||||
{t('max')}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`text-th-fgd-1 pb-2 pt-4`}>{t('amount')}</div>
|
||||
<div className="flex">
|
||||
<Input
|
||||
type="number"
|
||||
|
@ -196,17 +184,20 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
{invalidAmountMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="pt-3 pb-4">
|
||||
<Slider
|
||||
value={sliderPercentage}
|
||||
onChange={(v) => onChangeSlider(v)}
|
||||
step={1}
|
||||
maxButtonTransition={maxButtonTransition}
|
||||
<div className="pt-1">
|
||||
<ButtonGroup
|
||||
activeValue={depositPercentage}
|
||||
onChange={(v) => onChangeAmountButtons(v)}
|
||||
unit="%"
|
||||
values={['25', '50', '75', '100']}
|
||||
/>
|
||||
</div>
|
||||
<div className={`pt-8 flex justify-center`}>
|
||||
<div className={`flex justify-center pt-6`}>
|
||||
<Button
|
||||
disabled={inputAmount <= 0 || inputAmount > selectedAccount.uiBalance}
|
||||
disabled={
|
||||
parseFloat(inputAmount) <= 0 ||
|
||||
parseFloat(inputAmount) > selectedAccount.uiBalance
|
||||
}
|
||||
onClick={handleNewAccountDeposit}
|
||||
className="w-full"
|
||||
>
|
||||
|
@ -216,8 +207,8 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex text-th-fgd-4 text-xxs mt-1 -mb-1">
|
||||
<div className="mx-auto">{t('insufficient-sol')}</div>
|
||||
<div className="pt-3">
|
||||
<InlineNotification desc={t('interest-info')} type="info" />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -5,7 +5,6 @@ import { ElementTitle } from './styles'
|
|||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { floorToDecimal, tokenPrecision } from '../utils/index'
|
||||
import Loading from './Loading'
|
||||
import Slider from './Slider'
|
||||
import Button, { LinkButton } from './Button'
|
||||
import Switch from './Switch'
|
||||
import Tooltip from './Tooltip'
|
||||
|
@ -29,6 +28,7 @@ import {
|
|||
} from '@blockworks-foundation/mango-client'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import ButtonGroup from './ButtonGroup'
|
||||
|
||||
interface WithdrawModalProps {
|
||||
onClose: () => void
|
||||
|
@ -56,8 +56,7 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
const [includeBorrow, setIncludeBorrow] = useState(borrow)
|
||||
const [simulation, setSimulation] = useState(null)
|
||||
const [showSimulation, setShowSimulation] = useState(false)
|
||||
const [sliderPercentage, setSliderPercentage] = useState(0)
|
||||
const [maxButtonTransition, setMaxButtonTransition] = useState(false)
|
||||
const [withdrawPercentage, setWithdrawPercentage] = useState('')
|
||||
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
|
@ -196,7 +195,7 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
|
||||
const handleSetSelectedAsset = (symbol) => {
|
||||
setInputAmount('')
|
||||
setSliderPercentage(0)
|
||||
setWithdrawPercentage('')
|
||||
setWithdrawTokenSymbol(symbol)
|
||||
}
|
||||
|
||||
|
@ -249,31 +248,24 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
const handleIncludeBorrowSwitch = (checked) => {
|
||||
setIncludeBorrow(checked)
|
||||
setInputAmount('')
|
||||
setSliderPercentage(0)
|
||||
setWithdrawPercentage('')
|
||||
setInvalidAmountMessage('')
|
||||
}
|
||||
|
||||
const setMaxForSelectedAsset = async () => {
|
||||
setInputAmount(maxAmount.toString())
|
||||
setSliderPercentage(100)
|
||||
setInvalidAmountMessage('')
|
||||
setMaxButtonTransition(true)
|
||||
}
|
||||
|
||||
const onChangeAmountInput = (amount: string) => {
|
||||
setInputAmount(amount)
|
||||
setSliderPercentage((Number(amount) / maxAmount) * 100)
|
||||
setWithdrawPercentage('')
|
||||
setInvalidAmountMessage('')
|
||||
}
|
||||
|
||||
const onChangeSlider = async (percentage) => {
|
||||
const onChangeAmountButtons = async (percentage) => {
|
||||
const amount = (percentage / 100) * maxAmount
|
||||
if (percentage === 100) {
|
||||
if (percentage === '100') {
|
||||
setInputAmount(maxAmount.toString())
|
||||
} else {
|
||||
setInputAmount(floorToDecimal(amount, token.decimals).toString())
|
||||
}
|
||||
setSliderPercentage(percentage)
|
||||
setWithdrawPercentage(percentage)
|
||||
setInvalidAmountMessage('')
|
||||
validateAmountInput(amount)
|
||||
}
|
||||
|
@ -314,13 +306,6 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
})
|
||||
}
|
||||
|
||||
// turn off slider transition for dragging slider handle interaction
|
||||
useEffect(() => {
|
||||
if (maxButtonTransition) {
|
||||
setMaxButtonTransition(false)
|
||||
}
|
||||
}, [maxButtonTransition])
|
||||
|
||||
if (!withdrawTokenSymbol) return null
|
||||
|
||||
return (
|
||||
|
@ -385,7 +370,7 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
<span>{t('borrow-funds')}</span>
|
||||
<Tooltip content={t('tooltip-interest-charged')}>
|
||||
<InformationCircleIcon
|
||||
className={`h-5 w-5 ml-2 text-th-fgd-3 cursor-help`}
|
||||
className={`h-5 w-5 ml-2 text-th-primary cursor-help`}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -397,18 +382,6 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
</div>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className="text-th-fgd-1">{t('amount')}</div>
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
className="font-normal text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
disabled={
|
||||
!includeBorrow &&
|
||||
getDepositsForSelectedAsset().eq(ZERO_I80F48)
|
||||
}
|
||||
onClick={setMaxForSelectedAsset}
|
||||
>
|
||||
{t('max')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Input
|
||||
|
@ -432,7 +405,7 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
<span
|
||||
className={`${getAccountStatusColor(
|
||||
simulation.initHealthRatio
|
||||
)} bg-th-bkg-1 border flex font-semibold h-10 items-center justify-center ml-2 rounded text-th-fgd-1 w-14`}
|
||||
)} bg-th-bkg-1 border flex font-semibold h-10 items-center justify-center ml-1 rounded text-th-fgd-1 w-14`}
|
||||
>
|
||||
{simulation.leverage.toFixed(2)}x
|
||||
</span>
|
||||
|
@ -445,16 +418,15 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
{invalidAmountMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="pt-3 pb-4">
|
||||
<Slider
|
||||
disabled={!withdrawTokenSymbol}
|
||||
value={sliderPercentage}
|
||||
onChange={(v) => onChangeSlider(v)}
|
||||
step={1}
|
||||
maxButtonTransition={maxButtonTransition}
|
||||
<div className="pt-1 pb-6">
|
||||
<ButtonGroup
|
||||
activeValue={withdrawPercentage}
|
||||
onChange={(v) => onChangeAmountButtons(v)}
|
||||
unit="%"
|
||||
values={['25', '50', '75', '100']}
|
||||
/>
|
||||
</div>
|
||||
<div className={`pt-8 flex justify-center`}>
|
||||
<div className={`flex justify-center`}>
|
||||
<Button
|
||||
onClick={() => setShowSimulation(true)}
|
||||
disabled={
|
||||
|
@ -529,7 +501,7 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
|
|||
{t('health-check')}
|
||||
<Tooltip content={t('tooltip-after-withdrawal')}>
|
||||
<InformationCircleIcon
|
||||
className={`h-5 w-5 ml-2 text-th-fgd-3 cursor-help`}
|
||||
className={`h-5 w-5 ml-2 text-th-primary cursor-help`}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
|
|
@ -105,13 +105,15 @@
|
|||
"hourly-funding": "Hourly Funding",
|
||||
"in-orders": "In Orders",
|
||||
"includes-borrow": "Includes borrow of",
|
||||
"initial-deposit": "Initial Deposit",
|
||||
"init-error": "Could not perform init margin account and deposit operation",
|
||||
"init-health": "Init Health",
|
||||
"insufficient-balance-deposit": "Insufficient balance. Reduce the amount to deposit",
|
||||
"insufficient-balance-withdraw": "Insufficient balance. Borrow funds to withdraw",
|
||||
"insufficient-sol": "You need 0.035 SOL to create a mango account.",
|
||||
"insufficient-sol": "You need 0.035 SOL to create a Mango Account.",
|
||||
"interest": "Interest",
|
||||
"interest-earned": "Total Interest Earned/Paid",
|
||||
"interest-info": "Interest is earned continuously on all deposits.",
|
||||
"ioc": "IOC",
|
||||
"learn": "Learn",
|
||||
"learn-more": "Learn more",
|
||||
|
|
|
@ -95,11 +95,13 @@
|
|||
"in-orders": "En pedidos",
|
||||
"init-error": "No se pudo realizar la operación de depósito y cuenta de margen inicial",
|
||||
"init-health": "Salud Init",
|
||||
"initial-deposit": "",
|
||||
"insufficient-balance-deposit": "Saldo insuficiente. Reducir la cantidad a depositar",
|
||||
"insufficient-balance-withdraw": "Saldo insuficiente. Pedir prestados fondos para retirar",
|
||||
"insufficient-sol": "Necesita 0.035 SOL para crear una cuenta de mango.",
|
||||
"interest": "Interés",
|
||||
"interest-earned": "Interés total devengado / pagado",
|
||||
"interest-info": "",
|
||||
"ioc": "IOC",
|
||||
"learn": "Aprender",
|
||||
"learn-more": "Aprender mas",
|
||||
|
|
|
@ -107,11 +107,13 @@
|
|||
"includes-borrow": "包括存入",
|
||||
"init-error": "创建保证金帐户与存款出错了",
|
||||
"init-health": "初始健康度",
|
||||
"initial-deposit": "",
|
||||
"insufficient-balance-deposit": "帐户余额不够。请减少存入数量",
|
||||
"insufficient-balance-withdraw": "帐户余额不够。您得以借贷而前往",
|
||||
"insufficient-sol": "创建Mango帐户最少需要0.035 SOL。",
|
||||
"interest": "利息",
|
||||
"interest-earned": "存借利息",
|
||||
"interest-info": "",
|
||||
"ioc": "IOC",
|
||||
"learn": "学习",
|
||||
"learn-more": "学习",
|
||||
|
|
|
@ -107,11 +107,13 @@
|
|||
"includes-borrow": "包括存入",
|
||||
"init-error": "創建保證金帳戶與存款出錯了",
|
||||
"init-health": "初始健康度",
|
||||
"initial-deposit": "",
|
||||
"insufficient-balance-deposit": "帳戶餘額不夠。請減少存入數量",
|
||||
"insufficient-balance-withdraw": "帳戶餘額不夠。您得以借貸而前往",
|
||||
"insufficient-sol": "創建Mango帳戶最少需要0.035 SOL。",
|
||||
"interest": "利息",
|
||||
"interest-earned": "存借利息",
|
||||
"interest-info": "",
|
||||
"ioc": "IOC",
|
||||
"learn": "學習",
|
||||
"learn-more": "學習",
|
||||
|
|
Loading…
Reference in New Issue