combine borrow and repay modals

This commit is contained in:
saml33 2022-12-18 23:30:49 +11:00
parent 7c58c11bea
commit d7ccc7b4a6
15 changed files with 207 additions and 132 deletions

View File

@ -10,20 +10,21 @@ import Image from 'next/legacy/image'
import React, { useCallback, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
import mangoStore from '@store/mangoStore'
import { ModalProps } from '../../types/modal'
import { INPUT_TOKEN_DEFAULT } from '../../utils/constants'
import { notify } from '../../utils/notifications'
import { floorToDecimal, formatFixedDecimals } from '../../utils/numbers'
import ActionTokenList from '../account/ActionTokenList'
import ButtonGroup from '../forms/ButtonGroup'
import Label from '../forms/Label'
import Button from '../shared/Button'
import InlineNotification from '../shared/InlineNotification'
import Loading from '../shared/Loading'
import Modal from '../shared/Modal'
import { EnterBottomExitBottom, FadeInFadeOut } from '../shared/Transitions'
import { withValueLimit } from '../swap/SwapForm'
import { getMaxWithdrawForBank } from '../swap/useTokenMax'
import {
ACCOUNT_ACTION_MODAL_INNER_HEIGHT,
INPUT_TOKEN_DEFAULT,
} from './../utils/constants'
import { notify } from './../utils/notifications'
import { floorToDecimal, formatFixedDecimals } from './../utils/numbers'
import ActionTokenList from './account/ActionTokenList'
import ButtonGroup from './forms/ButtonGroup'
import Label from './forms/Label'
import Button from './shared/Button'
import InlineNotification from './shared/InlineNotification'
import Loading from './shared/Loading'
import { EnterBottomExitBottom, FadeInFadeOut } from './shared/Transitions'
import { withValueLimit } from './swap/SwapForm'
import { getMaxWithdrawForBank } from './swap/useTokenMax'
import MaxAmountButton from '@components/shared/MaxAmountButton'
import HealthImpactTokenChange from '@components/HealthImpactTokenChange'
import Tooltip from '@components/shared/Tooltip'
@ -32,13 +33,12 @@ import useJupiterMints from 'hooks/useJupiterMints'
import useMangoGroup from 'hooks/useMangoGroup'
import TokenVaultWarnings from '@components/shared/TokenVaultWarnings'
interface BorrowModalProps {
interface BorrowFormProps {
onSuccess: () => void
token?: string
}
type ModalCombinedProps = BorrowModalProps & ModalProps
function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
function BorrowForm({ onSuccess, token }: BorrowFormProps) {
const { t } = useTranslation('common')
const { group } = useMangoGroup()
const [inputAmount, setInputAmount] = useState('')
@ -114,7 +114,9 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
type: 'success',
txid: tx,
})
actions.reloadMangoAccount()
await actions.reloadMangoAccount()
setSubmitting(false)
onSuccess()
} catch (e: any) {
console.error(e)
notify({
@ -123,9 +125,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
txid: e?.txid,
type: 'error',
})
} finally {
setSubmitting(false)
onClose()
}
}
@ -165,12 +165,12 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
: false
return (
<Modal isOpen={isOpen} onClose={onClose}>
<>
<EnterBottomExitBottom
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-auto rounded-lg bg-th-bkg-1 p-6"
show={showTokenList}
>
<h2 className="mb-4 text-center">{t('select-token')}</h2>
<h2 className="mb-4 text-center text-lg">{t('select-borrow-token')}</h2>
<div className="grid auto-cols-fr grid-flow-col px-4 pb-2">
<div className="">
<p className="text-xs">{t('token')}</p>
@ -190,9 +190,11 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
valueKey="maxAmount"
/>
</EnterBottomExitBottom>
<FadeInFadeOut className="flex flex-col justify-between" show={isOpen}>
<FadeInFadeOut
className={`flex h-[${ACCOUNT_ACTION_MODAL_INNER_HEIGHT}] flex-col justify-between`}
show={!showTokenList}
>
<div>
<h2 className="mb-4 text-center">{t('borrow')}</h2>
{initHealth && initHealth <= 0 ? (
<div className="mb-4">
<InlineNotification
@ -203,7 +205,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
) : null}
<div className="grid grid-cols-2">
<div className="col-span-2 flex justify-between">
<Label text={t('token')} />
<Label text={`${t('borrow')} ${t('token')}`} />
<MaxAmountButton
className="mb-2"
label={t('max')}
@ -301,6 +303,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
</div>
) : null}
</div>
<div className="flex justify-center">
<Button
onClick={handleWithdraw}
className="flex w-full items-center justify-center"
@ -326,9 +329,10 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
<TokenVaultWarnings bank={bank} />
</div>
) : null}
</div>
</FadeInFadeOut>
</Modal>
</>
)
}
export default BorrowModal
export default BorrowForm

View File

@ -12,7 +12,11 @@ import Image from 'next/legacy/image'
import React, { useCallback, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
import mangoStore from '@store/mangoStore'
import { ALPHA_DEPOSIT_LIMIT, INPUT_TOKEN_DEFAULT } from './../utils/constants'
import {
ACCOUNT_ACTION_MODAL_INNER_HEIGHT,
ALPHA_DEPOSIT_LIMIT,
INPUT_TOKEN_DEFAULT,
} from './../utils/constants'
import { notify } from './../utils/notifications'
import { floorToDecimal, formatFixedDecimals } from './../utils/numbers'
import { TokenAccount } from './../utils/tokens'
@ -219,7 +223,7 @@ function DepositForm({ onSuccess, token }: DepositFormProps) {
/>
</EnterBottomExitBottom>
<FadeInFadeOut
className="flex h-full flex-col justify-between"
className={`flex h-[${ACCOUNT_ACTION_MODAL_INNER_HEIGHT}] flex-col justify-between`}
show={!showTokenList}
>
<div>

View File

@ -12,32 +12,30 @@ import Image from 'next/legacy/image'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
import mangoStore from '@store/mangoStore'
import { ModalProps } from '../../types/modal'
import { notify } from '../../utils/notifications'
import { floorToDecimal, formatFixedDecimals } from '../../utils/numbers'
import ActionTokenList from '../account/ActionTokenList'
import ButtonGroup from '../forms/ButtonGroup'
import Label from '../forms/Label'
import Button from '../shared/Button'
import Loading from '../shared/Loading'
import Modal from '../shared/Modal'
import { EnterBottomExitBottom, FadeInFadeOut } from '../shared/Transitions'
import { withValueLimit } from '../swap/SwapForm'
import { notify } from './../utils/notifications'
import { floorToDecimal, formatFixedDecimals } from './../utils/numbers'
import ActionTokenList from './account/ActionTokenList'
import ButtonGroup from './forms/ButtonGroup'
import Label from './forms/Label'
import Button from './shared/Button'
import Loading from './shared/Loading'
import { EnterBottomExitBottom, FadeInFadeOut } from './shared/Transitions'
import { withValueLimit } from './swap/SwapForm'
import MaxAmountButton from '@components/shared/MaxAmountButton'
import HealthImpactTokenChange from '@components/HealthImpactTokenChange'
import { walletBalanceForToken } from '../DepositForm'
import { walletBalanceForToken } from './DepositForm'
import SolBalanceWarnings from '@components/shared/SolBalanceWarnings'
import useMangoAccount from 'hooks/useMangoAccount'
import useJupiterMints from 'hooks/useJupiterMints'
import useMangoGroup from 'hooks/useMangoGroup'
import { ACCOUNT_ACTION_MODAL_INNER_HEIGHT } from 'utils/constants'
interface RepayModalProps {
interface RepayFormProps {
onSuccess: () => void
token?: string
}
type ModalCombinedProps = RepayModalProps & ModalProps
function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
function RepayForm({ onSuccess, token }: RepayFormProps) {
const { t } = useTranslation('common')
const { group } = useMangoGroup()
const { mangoAccount } = useMangoAccount()
@ -115,8 +113,8 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
if (!mangoAccount || !group || !bank || !wallet) return
console.log('inputAmount: ', amount)
try {
setSubmitting(true)
try {
const tx = await client.tokenDeposit(
group,
mangoAccount,
@ -132,6 +130,7 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
await actions.reloadMangoAccount()
actions.fetchWalletTokens(wallet.adapter as unknown as Wallet)
setSubmitting(false)
onSuccess()
} catch (e: any) {
notify({
title: 'Transaction failed',
@ -140,11 +139,10 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
type: 'error',
})
console.error('Error repaying:', e)
setSubmitting(false)
}
onClose()
},
[bank, wallet, onClose]
[bank, wallet]
)
const banks = useMemo(() => {
@ -174,13 +172,13 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
const showInsufficientBalance = walletBalance.maxAmount < Number(inputAmount)
return (
<Modal isOpen={isOpen} onClose={onClose}>
return banks.length ? (
<>
<EnterBottomExitBottom
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-auto rounded-lg bg-th-bkg-1 p-6"
show={showTokenList}
>
<h2 className="mb-4 text-center">{t('select-token')}</h2>
<h2 className="mb-4 text-center text-lg">{t('select-repay-token')}</h2>
<div className="grid auto-cols-fr grid-flow-col px-4 pb-2">
<div className="text-left">
<p className="text-xs">{t('token')}</p>
@ -197,19 +195,20 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
/>
</EnterBottomExitBottom>
<FadeInFadeOut
className="flex h-full flex-col justify-between"
show={isOpen}
className={`flex h-[${ACCOUNT_ACTION_MODAL_INNER_HEIGHT}] flex-col justify-between`}
show={!showTokenList}
>
<div>
<h2 className="mb-2 text-center">{t('repay-borrow')}</h2>
<div className="-mt-2 mb-2">
<SolBalanceWarnings
amount={inputAmount}
setAmount={setInputAmount}
selectedToken={selectedToken}
/>
<div className="mt-4 grid grid-cols-2">
</div>
<div className="grid grid-cols-2">
<div className="col-span-2 flex justify-between">
<Label text={t('token')} />
<Label text={`${t('repay')} ${t('token')}`} />
<MaxAmountButton
className="mb-2"
label={t('amount-owed')}
@ -298,6 +297,7 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
</p>
</div>
</div>
</div>
<Button
onClick={() => handleDeposit(inputAmount)}
className="flex w-full items-center justify-center"
@ -320,10 +320,14 @@ function RepayModal({ isOpen, onClose, token }: ModalCombinedProps) {
</div>
)}
</Button>
</div>
</FadeInFadeOut>
</Modal>
</>
) : (
<div className="flex h-[356px] flex-col items-center justify-center">
<span className="text-2xl">😎</span>
<p>No borrows to repay...</p>
</div>
)
}
export default RepayModal
export default RepayForm

View File

@ -1,5 +1,4 @@
import Link from 'next/link'
import TradeIcon from './icons/TradeIcon'
import {
EllipsisHorizontalIcon,
BuildingLibraryIcon,
@ -10,6 +9,7 @@ import {
ChartBarIcon,
Cog8ToothIcon,
ArrowsRightLeftIcon,
ArrowTrendingUpIcon,
} from '@heroicons/react/20/solid'
import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
@ -87,7 +87,7 @@ const SideNav = ({ collapsed }: { collapsed: boolean }) => {
<MenuItem
active={pathname === '/trade'}
collapsed={collapsed}
icon={<TradeIcon className="h-5 w-5" />}
icon={<ArrowTrendingUpIcon className="h-5 w-5" />}
title={t('trade')}
pagePath="/trade"
/>

View File

@ -20,18 +20,17 @@ import {
} from '../utils/numbers'
import { breakpoints } from '../utils/theme'
import Switch from './forms/Switch'
import BorrowModal from './modals/BorrowModal'
import { IconButton, LinkButton } from './shared/Button'
import ContentBox from './shared/ContentBox'
import IconDropMenu from './shared/IconDropMenu'
import Tooltip from './shared/Tooltip'
import { formatTokenSymbol } from 'utils/tokens'
import RepayModal from './modals/RepayModal'
import useMangoAccount from 'hooks/useMangoAccount'
import useJupiterMints from '../hooks/useJupiterMints'
import { Table, Td, Th, TrBody, TrHead } from './shared/TableElements'
import useMangoGroup from 'hooks/useMangoGroup'
import DepositWithdrawModal from './modals/DepositWithdrawModal'
import BorrowRepayModal from './modals/BorrowRepayModal'
const TokenList = () => {
const { t } = useTranslation(['common', 'token', 'trade'])
@ -569,14 +568,16 @@ const ActionsMenu = ({
/>
) : null}
{showBorrowModal ? (
<BorrowModal
<BorrowRepayModal
action="borrow"
isOpen={showBorrowModal}
onClose={() => setShowBorrowModal(false)}
token={selectedToken}
/>
) : null}
{showRepayModal ? (
<RepayModal
<BorrowRepayModal
action="repay"
isOpen={showRepayModal}
onClose={() => setShowRepayModal(false)}
token={selectedToken}

View File

@ -11,7 +11,10 @@ import { useCallback, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
import mangoStore from '@store/mangoStore'
import { INPUT_TOKEN_DEFAULT } from './../utils/constants'
import {
ACCOUNT_ACTION_MODAL_INNER_HEIGHT,
INPUT_TOKEN_DEFAULT,
} from './../utils/constants'
import { notify } from './../utils/notifications'
import { floorToDecimal, formatFixedDecimals } from './../utils/numbers'
import ActionTokenList from './account/ActionTokenList'
@ -184,7 +187,7 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
/>
</EnterBottomExitBottom>
<FadeInFadeOut
className="flex h-[386px] flex-col justify-between"
className={`flex h-[${ACCOUNT_ACTION_MODAL_INNER_HEIGHT}] flex-col justify-between`}
show={!showTokenList}
>
<div>

View File

@ -1,8 +1,8 @@
import { useMemo, useState } from 'react'
import Button, { LinkButton } from '../shared/Button'
import {
ArrowUpTrayIcon,
BanknotesIcon,
ArrowDownRightIcon,
ArrowUpLeftIcon,
DocumentDuplicateIcon,
EllipsisHorizontalIcon,
PencilIcon,
@ -20,11 +20,10 @@ import {
HealthType,
toUiDecimalsForQuote,
} from '@blockworks-foundation/mango-v4'
import RepayModal from '@components/modals/RepayModal'
import DelegateModal from '@components/modals/DelegateModal'
import useMangoAccount from 'hooks/useMangoAccount'
import useMangoGroup from 'hooks/useMangoGroup'
import BorrowModal from '@components/modals/BorrowModal'
import BorrowRepayModal from '@components/modals/BorrowRepayModal'
const AccountActions = () => {
const { t } = useTranslation(['common', 'close-account'])
@ -51,7 +50,7 @@ const AccountActions = () => {
return (
toUiDecimalsForQuote(
mangoAccount.getLiabsValue(group, HealthType.init).toNumber()
) >= 10
) >= 1
)
}, [mangoAccount, group])
@ -64,7 +63,7 @@ const AccountActions = () => {
disabled={!mangoAccount}
onClick={() => setShowRepayModal(true)}
>
<BanknotesIcon className="mr-2 h-5 w-5" />
<ArrowDownRightIcon className="mr-2 h-5 w-5" />
{t('repay')}
</Button>
) : null}
@ -74,7 +73,7 @@ const AccountActions = () => {
onClick={() => setShowBorrowModal(true)}
secondary={hasBorrows}
>
<ArrowUpTrayIcon className="mr-2 h-5 w-5" />
<ArrowUpLeftIcon className="mr-2 h-5 w-5" />
{t('borrow')}
</Button>
<IconDropMenu
@ -130,14 +129,15 @@ const AccountActions = () => {
/>
) : null}
{showBorrowModal ? (
<BorrowModal
<BorrowRepayModal
action="borrow"
isOpen={showBorrowModal}
onClose={() => setShowBorrowModal(false)}
/>
) : null}
{showRepayModal ? (
<RepayModal
<BorrowRepayModal
action="repay"
isOpen={showRepayModal}
onClose={() => setShowRepayModal(false)}
/>

View File

@ -0,0 +1,45 @@
import { ModalProps } from '../../types/modal'
import Modal from '../shared/Modal'
import { useState } from 'react'
import TabUnderline from '@components/shared/TabUnderline'
import BorrowForm from '@components/BorrowForm'
import RepayForm from '@components/RepayForm'
import { ACCOUNT_ACTION_MODAL_HEIGHT } from 'utils/constants'
interface BorrowRepayModalProps {
action: 'borrow' | 'repay'
token?: string
}
type ModalCombinedProps = BorrowRepayModalProps & ModalProps
const BorrowRepayModal = ({
action,
isOpen,
onClose,
token,
}: ModalCombinedProps) => {
const [activeTab, setActiveTab] = useState(action)
return (
<Modal isOpen={isOpen} onClose={onClose}>
<div className={`h-[${ACCOUNT_ACTION_MODAL_HEIGHT}]`}>
<div className="pb-2">
<TabUnderline
activeValue={activeTab}
values={['borrow', 'repay']}
onChange={(v) => setActiveTab(v)}
/>
</div>
{activeTab === 'borrow' ? (
<BorrowForm onSuccess={onClose} token={token} />
) : null}
{activeTab === 'repay' ? (
<RepayForm onSuccess={onClose} token={token} />
) : null}
</div>
</Modal>
)
}
export default BorrowRepayModal

View File

@ -1,5 +1,5 @@
import { Bank } from '@blockworks-foundation/mango-v4'
import BorrowModal from '@components/modals/BorrowModal'
import BorrowRepayModal from '@components/modals/BorrowRepayModal'
import DepositWithdrawModal from '@components/modals/DepositWithdrawModal'
import Button from '@components/shared/Button'
import mangoStore from '@store/mangoStore'
@ -95,7 +95,8 @@ const ActionPanel = ({ bank }: { bank: Bank }) => {
/>
) : null}
{showBorrowModal ? (
<BorrowModal
<BorrowRepayModal
action="borrow"
isOpen={showBorrowModal}
onClose={() => setShowBorrowModal(false)}
token={bank!.name}

View File

@ -94,7 +94,9 @@
"repayment-value": "Repayment Value",
"rolling-change": "24h Change",
"save": "Save",
"select-borrow-token": "Select Borrow Token",
"select-deposit-token": "Select Deposit Token",
"select-repay-token": "Select Repay Token",
"select-token": "Select Token",
"select-withdraw-token": "Select Withdraw Token",
"sell": "Sell",

View File

@ -94,7 +94,9 @@
"repayment-value": "Repayment Value",
"rolling-change": "24h Change",
"save": "Save",
"select-borrow-token": "Select Borrow Token",
"select-deposit-token": "Select Deposit Token",
"select-repay-token": "Select Repay Token",
"select-token": "Select Token",
"select-withdraw-token": "Select Withdraw Token",
"sell": "Sell",

View File

@ -94,7 +94,9 @@
"repayment-value": "Repayment Value",
"rolling-change": "24h Change",
"save": "Save",
"select-borrow-token": "Select Borrow Token",
"select-deposit-token": "Select Deposit Token",
"select-repay-token": "Select Repay Token",
"select-token": "Select Token",
"select-withdraw-token": "Select Withdraw Token",
"sell": "Sell",

View File

@ -94,7 +94,9 @@
"repayment-value": "Repayment Value",
"rolling-change": "24h Change",
"save": "Save",
"select-borrow-token": "Select Borrow Token",
"select-deposit-token": "Select Deposit Token",
"select-repay-token": "Select Repay Token",
"select-token": "Select Token",
"select-withdraw-token": "Select Withdraw Token",
"sell": "Sell",

View File

@ -94,7 +94,9 @@
"repayment-value": "Repayment Value",
"rolling-change": "24h Change",
"save": "Save",
"select-borrow-token": "Select Borrow Token",
"select-deposit-token": "Select Deposit Token",
"select-repay-token": "Select Repay Token",
"select-token": "Select Token",
"select-withdraw-token": "Select Withdraw Token",
"sell": "Sell",

View File

@ -48,6 +48,9 @@ export const GRID_LAYOUT_KEY = 'savedLayouts-0.1'
export const NOTIFICATION_POSITION_KEY = 'notificationPosition'
export const FAVORITE_MARKETS_KEY = 'favoriteMarkets'
export const MIN_SOL_BALANCE = 0.04
export const FAVORITE_MARKETS_KEY = 'favoriteMarkets'
export const ACCOUNT_ACTION_MODAL_HEIGHT = '448px'
export const ACCOUNT_ACTION_MODAL_INNER_HEIGHT = '386px'