mars-v2-frontend/components/Account/FundAccountModal.tsx
Linkie Link 2f7b266e6b
Mp 1671 header (#59)
* MP-1674: replaced the logo and added dekstop only nav

* MP-1677: borrowCapacity implemented into the SubAccount Nav

* MP-1677: adjusted the SubAccount navigation

* M1677: fixed the button and SearchInput component

* MP-1674: fixed the NavLink component

* MP-1674: fixed the SubAccount navigation

* tidy: cleaning up the trading view

* MP-1674: added withdraw and funding functions

* MP-1674: worked on the AccountStats

* MP-1671: modal work

* MP-1647: improvised CreditAccount expander

* tidy: fixed the page structure

* MP-1758: finished the SearchInput layout

* MP-1759: updated the semicircle graphs

* MP-1759: SemiCircle to Gauge

* fix: implemented animated numbers

* tidy: refactor

* MP-1759: added Tooltip to the Gauge

* fix: replace animate={true} with animate

* fix: fixed the Gauge timing

* fix: updated the BorrowCapacity styles

* fix: renamed SubAccount to Account

* fix: Text should not be a button, Button should be

* tidy: format

* fix: Text no clicky

* fix: replaced all the Text appearances with onClick
2022-12-06 10:20:22 +01:00

214 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Switch } from '@headlessui/react'
import BigNumber from 'bignumber.js'
import { useEffect, useMemo, useState } from 'react'
import { toast } from 'react-toastify'
import useLocalStorageState from 'use-local-storage-state'
import Button from 'components/Button'
import CircularProgress from 'components/CircularProgress'
import MarsProtocolLogo from 'components/Icons/mars-protocol.svg'
import Modal from 'components/Modal'
import Slider from 'components/Slider'
import Text from 'components/Text'
import useDepositCreditAccount from 'hooks/mutations/useDepositCreditAccount'
import useAllBalances from 'hooks/useAllBalances'
import useAllowedCoins from 'hooks/useAllowedCoins'
import useCreditManagerStore from 'stores/useCreditManagerStore'
import { getTokenDecimals, getTokenSymbol } from 'utils/tokens'
interface Props {
open: boolean
setOpen: (open: boolean) => void
}
const FundAccountModal = ({ open, setOpen }: Props) => {
const [amount, setAmount] = useState(0)
const [selectedToken, setSelectedToken] = useState('')
const selectedAccount = useCreditManagerStore((s) => s.selectedAccount)
const [lendAssets, setLendAssets] = useLocalStorageState(`lendAssets_${selectedAccount}`, {
defaultValue: false,
})
const { data: balancesData } = useAllBalances()
const { data: allowedCoinsData, isLoading: isLoadingAllowedCoins } = useAllowedCoins()
const { mutate, isLoading } = useDepositCreditAccount(
selectedAccount || '',
selectedToken,
BigNumber(amount)
.times(10 ** getTokenDecimals(selectedToken))
.toNumber(),
{
onSuccess: () => {
setAmount(0)
toast.success(`${amount} ${getTokenSymbol(selectedToken)} successfully Deposited`)
setOpen(false)
},
},
)
useEffect(() => {
if (allowedCoinsData && allowedCoinsData.length > 0) {
// initialize selected token when allowedCoins fetch data is available
setSelectedToken(allowedCoinsData[0])
}
}, [allowedCoinsData])
const walletAmount = useMemo(() => {
if (!selectedToken) return 0
return BigNumber(balancesData?.find((balance) => balance.denom === selectedToken)?.amount ?? 0)
.div(10 ** getTokenDecimals(selectedToken))
.toNumber()
}, [balancesData, selectedToken])
const handleValueChange = (value: number) => {
if (value > walletAmount) {
setAmount(walletAmount)
return
}
setAmount(value)
}
const maxValue = walletAmount
const percentageValue = isNaN(amount) ? 0 : (amount * 100) / maxValue
return (
<Modal open={open} setOpen={setOpen}>
<div className='flex min-h-[520px] w-full'>
{isLoading && (
<div className='absolute inset-0 z-40 grid place-items-center bg-black/50'>
<CircularProgress />
</div>
)}
<div className='flex flex-1 flex-col items-start justify-between bg-fund-modal bg-cover p-6'>
<div>
<Text size='2xs' uppercase={true} className='mb-3 text-white'>
About
</Text>
<Text size='xl' className='mb-4 text-white'>
Bringing the next generation of video creation to the Metaverse.
<br />
Powered by deep-learning.
</Text>
</div>
<div className='w-[153px] text-white'>
<MarsProtocolLogo />
</div>
</div>
<div className='flex flex-1 flex-col p-6'>
<Text size='xl' uppercase={true} className='mb-4 text-white'>
Account {selectedAccount}
</Text>
<div className='p-3" mb-2'>
<Text size='sm' uppercase={true} className='mb-1 text-white'>
Fund Account
</Text>
<Text size='sm' className='mb-6 text-white/60'>
Transfer assets from your injective wallet to your Mars credit account. If you dont
have any assets in your injective wallet use the injective bridge to transfer funds to
your injective wallet.
</Text>
{isLoadingAllowedCoins ? (
<p>Loading...</p>
) : (
<>
<div className='mb-4 rounded-md border border-white/20'>
<div className='mb-1 flex justify-between border-b border-white/20 p-2'>
<Text size='sm' className='text-white'>
Asset:
</Text>
<select
className='bg-transparent text-white outline-0'
onChange={(e) => {
setSelectedToken(e.target.value)
if (e.target.value !== selectedToken) setAmount(0)
}}
value={selectedToken}
>
{allowedCoinsData?.map((entry) => (
<option key={entry} value={entry}>
{getTokenSymbol(entry)}
</option>
))}
</select>
</div>
<div className='flex justify-between p-2'>
<Text size='sm' className='text-white'>
Amount:
</Text>
<input
type='number'
className='appearance-none bg-transparent text-right text-white'
value={amount}
min='0'
onChange={(e) => handleValueChange(e.target.valueAsNumber)}
onBlur={(e) => {
if (e.target.value === '') setAmount(0)
}}
/>
</div>
</div>
<Text size='xs' uppercase={true} className='mb-2 text-white/60'>
{`In wallet: ${walletAmount.toLocaleString()} ${getTokenSymbol(selectedToken)}`}
</Text>
<Slider
className='mb-6'
value={percentageValue}
onChange={(value) => {
const decimal = value[0] / 100
const tokenDecimals = getTokenDecimals(selectedToken)
// limit decimal precision based on token contract decimals
const newAmount = Number((decimal * maxValue).toFixed(tokenDecimals))
setAmount(newAmount)
}}
onMaxClick={() => setAmount(maxValue)}
/>
</>
)}
</div>
<div className='mb-2 flex items-center justify-between'>
<div>
<Text size='sm' uppercase={true} className='mb-1 text-white'>
Lending Assets
</Text>
<Text size='sm' className='text-white/60'>
Lend assets from account to earn yield.
</Text>
</div>
<Switch
checked={lendAssets}
onChange={setLendAssets}
className={`${
lendAssets ? 'bg-blue-600' : 'bg-gray-400'
} relative inline-flex h-6 w-11 items-center rounded-full`}
>
<span
className={`${
lendAssets ? 'translate-x-6' : 'translate-x-1'
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</Switch>
</div>
<Button
className='mt-auto w-full'
onClick={() => mutate()}
disabled={amount === 0 || !amount}
>
Fund Account
</Button>
</div>
</div>
</Modal>
)
}
export default FundAccountModal