diff --git a/package.json b/package.json index e3ccb61c..f22f8ef9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@cosmjs/cosmwasm-stargate": "^0.30.1", "@cosmjs/stargate": "^0.30.1", "@marsprotocol/wallet-connector": "^1.5.8", - "@sentry/nextjs": "^7.51.0", + "@sentry/nextjs": "^7.51.2", "@tanstack/react-table": "^8.9.1", "@tippyjs/react": "^4.2.6", "bignumber.js": "^9.1.1", @@ -30,14 +30,14 @@ "react-spring": "^9.7.1", "react-toastify": "^9.1.2", "react-use-clipboard": "^1.0.9", - "recharts": "^2.5.0", + "recharts": "^2.6.0", "swr": "^2.1.5", "tailwind-scrollbar-hide": "^1.1.7", "zustand": "^4.3.8" }, "devDependencies": { - "@svgr/webpack": "^7.0.0", - "@types/node": "^20.1.0", + "@svgr/webpack": "^8.0.1", + "@types/node": "^20.1.1", "@types/react": "18.2.6", "@types/react-dom": "18.2.4", "autoprefixer": "^10.4.14", diff --git a/src/components/Account/AccountComposition.tsx b/src/components/Account/AccountComposition.tsx index 4cc7531c..17ddfe3b 100644 --- a/src/components/Account/AccountComposition.tsx +++ b/src/components/Account/AccountComposition.tsx @@ -3,14 +3,15 @@ import BigNumber from 'bignumber.js' import classNames from 'classnames' import DisplayCurrency from 'components/DisplayCurrency' +import { FormattedNumber } from 'components/FormattedNumber' import { ArrowRight } from 'components/Icons' import Text from 'components/Text' import useStore from 'store' import { calculateAccountApr, - calculateAccountBalance, calculateAccountBorrowRate, calculateAccountDebt, + calculateAccountDeposits, calculateAccountPnL, } from 'utils/accounts' import { BN } from 'utils/helpers' @@ -25,12 +26,14 @@ interface ItemProps { current: BigNumber change: BigNumber className?: string + isBadIncrease?: boolean + isPercentage?: boolean } export default function AccountComposition(props: Props) { const prices = useStore((s) => s.prices) - const balance = calculateAccountBalance(props.account, prices) - const balanceChange = props.change ? calculateAccountBalance(props.change, prices) : BN(0) + const balance = calculateAccountDeposits(props.account, prices) + const balanceChange = props.change ? calculateAccountDeposits(props.change, prices) : BN(0) const debtBalance = calculateAccountDebt(props.account, prices) const debtBalanceChange = props.change ? calculateAccountDebt(props.change, prices) : BN(0) const pnL = calculateAccountPnL(props.account, prices) @@ -53,6 +56,7 @@ export default function AccountComposition(props: Props) { current={debtBalance} change={debtBalance.plus(debtBalanceChange)} className='pb-3' + isBadIncrease /> - - + + ) } function Item(props: ItemProps) { const baseCurrency = useStore((s) => s.baseCurrency) - const increase = props.current.isLessThan(props.change) + const increase = props.isBadIncrease + ? props.current.isGreaterThan(props.change) + : props.current.isLessThan(props.change) return (
@@ -77,19 +89,35 @@ function Item(props: ItemProps) {
- + {props.isPercentage ? ( + + ) : ( + + )} {!props.current.isEqualTo(props.change) && ( <> - + {props.isPercentage ? ( + + ) : ( + + )} )}
diff --git a/src/components/Account/AccountList.tsx b/src/components/Account/AccountList.tsx index e97d8507..c7bd4706 100644 --- a/src/components/Account/AccountList.tsx +++ b/src/components/Account/AccountList.tsx @@ -13,7 +13,7 @@ import SwitchWithLabel from 'components/SwitchWithLabel' import Text from 'components/Text' import useToggle from 'hooks/useToggle' import useStore from 'store' -import { calculateAccountBalance } from 'utils/accounts' +import { calculateAccountDeposits } from 'utils/accounts' import { hardcodedFee } from 'utils/contants' import { BN } from 'utils/helpers' import useParams, { getRoute } from 'utils/route' @@ -41,7 +41,7 @@ export default function AccountList(props: Props) { const accountSelected = !!selectedAccount && !isNaN(Number(selectedAccount)) const selectedAccountDetails = props.accounts.find((account) => account.id === selectedAccount) const selectedAccountBalance = selectedAccountDetails - ? calculateAccountBalance(selectedAccountDetails, prices) + ? calculateAccountDeposits(selectedAccountDetails, prices) : BN(0) async function deleteAccountHandler() { @@ -69,7 +69,7 @@ export default function AccountList(props: Props) { return (
{props.accounts.map((account) => { - const positionBalance = calculateAccountBalance(account, prices) + const positionBalance = calculateAccountDeposits(account, prices) const isActive = selectedAccount === account.id return (
diff --git a/src/components/Account/AccountMenu.tsx b/src/components/Account/AccountMenu.tsx index bdb14314..a2aa2da8 100644 --- a/src/components/Account/AccountMenu.tsx +++ b/src/components/Account/AccountMenu.tsx @@ -9,6 +9,7 @@ interface Props { } async function Content(props: Props) { + if (props.params.address === undefined) return null const accounts = await getAccounts(props.params.address) return } diff --git a/src/components/Account/AccountSummary.tsx b/src/components/Account/AccountSummary.tsx index 3a974dd2..93768596 100644 --- a/src/components/Account/AccountSummary.tsx +++ b/src/components/Account/AccountSummary.tsx @@ -8,7 +8,7 @@ import DisplayCurrency from 'components/DisplayCurrency' import { ArrowChartLineUp } from 'components/Icons' import Text from 'components/Text' import useStore from 'store' -import { calculateAccountBalance } from 'utils/accounts' +import { calculateAccountDeposits } from 'utils/accounts' import { BN } from 'utils/helpers' interface Props { @@ -19,7 +19,7 @@ interface Props { export default function AccountSummary(props: Props) { const prices = useStore((s) => s.prices) const baseCurrency = useStore((s) => s.baseCurrency) - const accountBalance = props.account ? calculateAccountBalance(props.account, prices) : BN(0) + const accountBalance = props.account ? calculateAccountDeposits(props.account, prices) : BN(0) if (!props.account) return null return ( diff --git a/src/components/Divider.tsx b/src/components/Divider.tsx index 72007fb6..cd57f1df 100644 --- a/src/components/Divider.tsx +++ b/src/components/Divider.tsx @@ -1,10 +1,13 @@ +import classNames from 'classnames' + interface Props { orientation?: 'horizontal' | 'vertical' + className?: string } export default function Divider(props: Props) { if (props.orientation === 'vertical') { - return
+ return
} - return
+ return
} diff --git a/src/components/Modals/BorrowModal.tsx b/src/components/Modals/BorrowModal.tsx index 00a26129..c2cd3682 100644 --- a/src/components/Modals/BorrowModal.tsx +++ b/src/components/Modals/BorrowModal.tsx @@ -1,5 +1,7 @@ +'use client' + import Image from 'next/image' -import { useState } from 'react' +import { useEffect, useState } from 'react' import AccountSummary from 'components/Account/AccountSummary' import { Button } from 'components/Button' @@ -7,16 +9,17 @@ import Card from 'components/Card' import Divider from 'components/Divider' import { ArrowRight } from 'components/Icons' import Modal from 'components/Modal' +import Select from 'components/Select/Select' import Text from 'components/Text' import TitleAndSubCell from 'components/TitleAndSubCell' import TokenInputWithSlider from 'components/TokenInputWithSlider' import { ASSETS } from 'constants/assets' import useCurrentAccount from 'hooks/useCurrentAccount' +import useToggle from 'hooks/useToggle' import useStore from 'store' import { hardcodedFee } from 'utils/contants' import { formatPercent, formatValue } from 'utils/formatters' import { BN } from 'utils/helpers' -import useParams from 'utils/route' function getDebtAmount(modal: BorrowModal | null) { if (!(modal?.marketData as BorrowAssetActive)?.debt) return '0' @@ -29,46 +32,57 @@ function getAssetLogo(modal: BorrowModal | null) { } export default function BorrowModal() { - const params = useParams() const currentAccount = useCurrentAccount() const [percentage, setPercentage] = useState(0) const [amount, setAmount] = useState(BN(0)) - const [selectedAccount, setSelectedAccount] = useState(params.accountId) + const [change, setChange] = useState() + const [selectedAccount, setSelectedAccount] = useState(currentAccount) + const [isConfirming, setIsConfirming] = useToggle() const modal = useStore((s) => s.borrowModal) const borrow = useStore((s) => s.borrow) const repay = useStore((s) => s.repay) const asset = modal?.asset ?? ASSETS[0] - const accounts = useStore((s) => s.accounts)?.map((account) => { - return account.id + const accounts = useStore((s) => s.accounts) + const accountOptions = accounts?.map((account) => { + return { value: account.id, label: `Account ${account.id}` } }) + const isRepay = modal?.isRepay ?? false - function onAccountSelect(accountId: string) { - setSelectedAccount(accountId) + function resetState() { + setAmount(BN(0)) + setPercentage(0) + setIsConfirming(false) } - function onConfirmClick() { + async function onConfirmClick() { if (!modal?.asset) return - if (modal.isRepay) { - repay({ + setIsConfirming(true) + let result + if (isRepay) { + result = await repay({ fee: hardcodedFee, - accountId: selectedAccount, + accountId: selectedAccount?.id ?? '0', coin: { denom: modal.asset.denom, amount: amount.toString() }, accountBalance: percentage === 100, }) - return + } else { + result = await borrow({ + fee: hardcodedFee, + accountId: selectedAccount?.id ?? '0', + coin: { denom: modal.asset.denom, amount: amount.toString() }, + }) } - borrow({ - fee: hardcodedFee, - accountId: selectedAccount, - coin: { denom: modal.asset.denom, amount: amount.toString() }, - }) + setIsConfirming(false) + if (result) { + resetState() + useStore.setState({ borrowModal: null }) + } } function onClose() { + resetState() useStore.setState({ borrowModal: null }) - setAmount(BN(0)) - setPercentage(0) } const liquidityAmountString = formatValue(modal?.marketData?.liquidity?.amount || 0, { @@ -81,7 +95,31 @@ export default function BorrowModal() { decimals: 6, }) - const max = BN(modal?.isRepay ? getDebtAmount(modal) : liquidityAmountString) + const max = BN(isRepay ? getDebtAmount(modal) : modal?.marketData?.liquidity?.amount ?? '0') + + useEffect(() => { + if (!selectedAccount) + setSelectedAccount(currentAccount) + }, [selectedAccount, currentAccount]) + + useEffect(() => { + if (!modal?.asset) return + + setChange({ + deposits: [ + { + amount: isRepay ? BN(0).minus(amount).toString() : BN(0).plus(amount).toString(), + denom: modal.asset.denom, + }, + ], + debts: [ + { + amount: isRepay ? BN(0).minus(amount).toString() : BN(0).plus(amount).toString(), + denom: modal.asset.denom, + }, + ], + }) + }, [amount, modal?.asset, currentAccount, isRepay]) return ( {getAssetLogo(modal)} - {modal?.isRepay ? 'Repay' : 'Borrow'} {asset.symbol} + {isRepay ? 'Repay' : 'Borrow'} {asset.symbol} } @@ -119,39 +157,43 @@ export default function BorrowModal() {
- { - setAmount(val) - }} - amount={amount} - max={max} - /> - - {modal?.isRepay ? 'Repay for' : 'Borrow to'} - +
+ + + + {isRepay ? 'Repay for' : 'Borrow to'} + +
+