3022ae9a6a
* 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
170 lines
6.1 KiB
TypeScript
170 lines
6.1 KiB
TypeScript
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 don’t 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
|