mars-v2-frontend/components/CreditManager/FundAccount.tsx
Gustavo Mauricio 3022ae9a6a
MP-2017: Deposit Funds and Account stats (#21)
* style: fund account font size adjustments

* client instance. contract addresses updates. prices hook added

* persist lend assets value for every credit account

* feat: account stats and semi circular progress

* minor code cleanup

* display borrowed assets interest rate

* fallback screen when no wallet is connected

* fix: hydration mismatch

* update osmosis testnet endpoints

* style: body text color

* coin interface imported from cosmos package

* risk calculation from ltv assets comment added

* svgr setup. inline svg extracted to Icons folder

* address removed from local storage. wallet store improvements

* rename setAddress action to connect

* yield page renamed to earn

* refactor: accountStats using BigNumber

* update contract addresses

* update hardcoded fee

* update market mocked values

* current leverage added to useAccountStats hook return

* leverage naming disambiguation

* debt positions labels color update. negative sign before values

* remove prefers-color-scheme media query

* update redbank mock data
2022-10-12 16:41:03 +01:00

170 lines
6.1 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 React, { useEffect, useMemo, useState } from 'react'
import * as Slider from '@radix-ui/react-slider'
import BigNumber from 'bignumber.js'
import { Switch } from '@headlessui/react'
import useLocalStorageState from 'use-local-storage-state'
import Button from '../Button'
import useAllowedCoins from 'hooks/useAllowedCoins'
import useDepositCreditAccount from 'hooks/useDepositCreditAccount'
import useCreditManagerStore from 'stores/useCreditManagerStore'
import useAllBalances from 'hooks/useAllBalances'
import { getTokenDecimals, getTokenSymbol } from 'utils/tokens'
import CreditManagerContainer from './CreditManagerContainer'
const FundAccount = () => {
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 } = useDepositCreditAccount(
selectedAccount || '',
selectedToken,
BigNumber(amount)
.times(10 ** getTokenDecimals(selectedToken))
.toNumber()
)
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 (
<>
<CreditManagerContainer className="mb-2 p-3">
<p className="mb-6 text-sm">
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.
</p>
{isLoadingAllowedCoins ? (
<p>Loading...</p>
) : (
<>
<div className="mb-4 text-sm">
<div className="mb-1 flex justify-between">
<div>Asset:</div>
<select
className="bg-transparent"
onChange={(e) => {
setSelectedToken(e.target.value)
if (e.target.value !== selectedToken) setAmount(0)
}}
>
{allowedCoinsData?.map((entry) => (
<option key={entry} value={entry}>
{getTokenSymbol(entry)}
</option>
))}
</select>
</div>
<div className="flex justify-between">
<div>Amount:</div>
<input
type="number"
className="border border-black/50 bg-transparent px-2"
value={amount}
onChange={(e) => handleValueChange(e.target.valueAsNumber)}
/>
</div>
</div>
<p className="text-sm">In wallet: {walletAmount.toLocaleString()}</p>
{/* SLIDER - initial implementation to test functionality */}
{/* TODO: will need to be revamped later on */}
<div className="relative mb-6 flex flex-1 items-center">
<Slider.Root
className="relative flex h-[20px] w-full cursor-pointer touch-none select-none items-center"
value={[percentageValue]}
min={0}
max={100}
step={1}
onValueChange={(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)
}}
>
<Slider.Track className="relative h-[6px] grow rounded-full bg-gray-400">
<Slider.Range className="absolute h-[100%] rounded-full bg-blue-600" />
</Slider.Track>
<Slider.Thumb className="flex h-[20px] w-[20px] items-center justify-center rounded-full bg-white !outline-none">
<div className="relative top-5 text-xs">{percentageValue.toFixed(0)}%</div>
</Slider.Thumb>
</Slider.Root>
<button
className="ml-4 rounded-md bg-blue-600 py-1 px-2 text-sm text-white"
onClick={() => setAmount(maxValue)}
>
MAX
</button>
</div>
</>
)}
</CreditManagerContainer>
<CreditManagerContainer className="mb-2 flex items-center justify-between">
<div>
<h3 className="font-bold">Lending Assets</h3>
<div className="text-sm opacity-50">Lend assets from account to earn yield.</div>
</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>
</CreditManagerContainer>
<Button
className="w-full !rounded-lg"
onClick={() => mutate()}
disabled={amount === 0 || !amount}
>
Fund
</Button>
</>
)
}
export default FundAccount