Merge in styling changes

This commit is contained in:
Tyler Shipe 2021-08-16 13:00:43 -04:00
parent 2fa3b81b74
commit 00a85cded2
6 changed files with 87 additions and 250 deletions

View File

@ -1,14 +1,6 @@
import React, { FunctionComponent, useEffect, useState } from 'react'
import { Disclosure } from '@headlessui/react'
import {
ExclamationCircleIcon,
InformationCircleIcon,
} from '@heroicons/react/outline'
import {
ChevronLeftIcon,
ChevronDownIcon,
ChevronUpIcon,
} from '@heroicons/react/solid'
import { ExclamationCircleIcon } from '@heroicons/react/outline'
import { ChevronLeftIcon } from '@heroicons/react/solid'
import Modal from './Modal'
import Input from './Input'
import AccountSelect from './AccountSelect'
@ -16,7 +8,6 @@ import { ElementTitle } from './styles'
import useMangoStore from '../stores/useMangoStore'
import Loading from './Loading'
import Button, { LinkButton } from './Button'
import Tooltip from './Tooltip'
import Slider from './Slider'
import InlineNotification from './InlineNotification'
import { deposit } from '../utils/mango'
@ -35,13 +26,9 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
settleDeficit,
tokenSymbol = '',
}) => {
// const groupConfig = useMangoGroupConfig()
// const tokenSymbols = useMemo(() => groupConfig.tokens.map(t => t.symbol), [groupConfig]);
const [inputAmount, setInputAmount] = useState<string>(settleDeficit || '')
const [submitting, setSubmitting] = useState(false)
const [simulation /*setSimulation*/] = useState(null)
const [showSimulation, setShowSimulation] = useState(false)
const [showConfirm, setShowConfirm] = useState(false)
const [invalidAmountMessage, setInvalidAmountMessage] = useState('')
const [sliderPercentage, setSliderPercentage] = useState(0)
const [maxButtonTransition, setMaxButtonTransition] = useState(false)
@ -50,9 +37,6 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
const setMangoStore = useMangoStore((s) => s.set)
const [selectedAccount, setSelectedAccount] = useState(walletTokens[0])
// const prices = [] //useMangoStore((s) => s.selectedMangoGroup.prices)
// const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
useEffect(() => {
if (tokenSymbol) {
const symbolAccount = walletTokens.find(
@ -79,54 +63,6 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
onClose()
}
/* TODO: simulation
useEffect(() => {
if (!selectedMangoGroup || !selectedMangoAccount || !selectedAccount)
return
const mintDecimals = selectedMangoGroup.mintDecimals[tokenIndex]
const groupIndex = selectedMangoGroup.indexes[tokenIndex]
const deposits = selectedMangoAccount.getUiDeposit(
selectedMangoGroup,
tokenIndex
)
// simulate change to deposits based on input amount
const newDeposit = Math.max(0, +inputAmount + +deposits)
// clone MangoAccount and arrays to not modify selectedMangoAccount
const simulation = new MangoAccount(null, selectedMangoAccount)
simulation.deposits = [...selectedMangoAccount.deposits]
simulation.borrows = [...selectedMangoAccount.borrows]
// update with simulated values
simulation.deposits[tokenIndex] =
uiToNative(newDeposit, mintDecimals).toNumber() / groupIndex.deposit
const equity = simulation.computeValue(selectedMangoGroup, prices)
const assetsVal = simulation.getAssetsVal(selectedMangoGroup, prices)
const liabsVal = simulation.getLiabsVal(selectedMangoGroup, prices)
const collateralRatio = simulation.getCollateralRatio(
selectedMangoGroup,
prices
)
const leverage = 1 / Math.max(0, collateralRatio - 1)
setSimulation({
equity,
assetsVal,
liabsVal,
collateralRatio,
leverage,
})
}, [
inputAmount,
prices,
tokenIndex,
selectedMangoAccount,
selectedMangoGroup,
])
*/
const handleAccountSelect = (account) => {
setInputAmount('')
setSliderPercentage(0)
@ -173,38 +109,6 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
})
}
const renderAccountRiskStatus = (
collateralRatio: number,
isRiskLevel?: boolean,
isStatusIcon?: boolean
) => {
if (collateralRatio < 1.25) {
return isRiskLevel ? (
<div className="text-th-red">High</div>
) : isStatusIcon ? (
'bg-th-red'
) : (
'border-th-red text-th-red'
)
} else if (collateralRatio > 1.25 && collateralRatio < 1.5) {
return isRiskLevel ? (
<div className="text-th-orange">Moderate</div>
) : isStatusIcon ? (
'bg-th-orange'
) : (
'border-th-orange text-th-orange'
)
} else {
return isRiskLevel ? (
<div className="text-th-green">Low</div>
) : isStatusIcon ? (
'bg-th-green'
) : (
'border-th-green text-th-green'
)
}
}
const validateAmountInput = (amount) => {
if (Number(amount) <= 0) {
setInvalidAmountMessage('Enter an amount to deposit')
@ -261,7 +165,7 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
return (
<Modal isOpen={isOpen} onClose={handleClose}>
{!showSimulation ? (
{!showConfirm ? (
<>
<Modal.Header>
<ElementTitle noMarignBottom>Deposit Funds</ElementTitle>
@ -306,20 +210,6 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
onChange={(e) => onChangeAmountInput(e.target.value)}
suffix={selectedAccount?.config.symbol}
/>
{/* {simulation ? (
<Tooltip content="Projected Leverage" className="py-1">
<span
className={`${renderAccountRiskStatus(
simulation?.collateralRatio
)} bg-th-bkg-1 border flex font-semibold h-10 items-center justify-center ml-2 rounded text-th-fgd-1 w-14`}
>
{simulation?.leverage < 5
? simulation?.leverage.toFixed(2)
: '>5'}
x
</span>
</Tooltip>
) : null} */}
</div>
{invalidAmountMessage ? (
<div className="flex items-center pt-1.5 text-th-red">
@ -338,9 +228,10 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
</div>
<div className={`pt-8 flex justify-center`}>
<Button
onClick={() => setShowSimulation(true)}
onClick={() => setShowConfirm(true)}
className="w-full"
disabled={
!inputAmount ||
parseFloat(inputAmount) <= 0 ||
!selectedAccount ||
parseFloat(inputAmount) > selectedAccount.uiBalance
@ -366,95 +257,6 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
</div>
</div>
</div>
{simulation ? (
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button
className={`border border-th-fgd-4 default-transition font-normal mt-4 pl-3 pr-2 py-2.5 ${
open ? 'rounded-b-none' : 'rounded-md'
} text-th-fgd-1 w-full hover:bg-th-bkg-3 focus:outline-none`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<span className="flex h-2 w-2 mr-2.5 relative">
<span
className={`animate-ping absolute inline-flex h-full w-full rounded-full ${renderAccountRiskStatus(
simulation?.collateralRatio,
false,
true
)} opacity-75`}
></span>
<span
className={`relative inline-flex rounded-full h-2 w-2 ${renderAccountRiskStatus(
simulation?.collateralRatio,
false,
true
)}`}
></span>
</span>
Account Health Check
<Tooltip content="The details of your account after this deposit.">
<InformationCircleIcon
className={`h-5 w-5 ml-2 text-th-fgd-3 cursor-help`}
/>
</Tooltip>
</div>
{open ? (
<ChevronUpIcon className="h-5 w-5 mr-1" />
) : (
<ChevronDownIcon className="h-5 w-5 mr-1" />
)}
</div>
</Disclosure.Button>
<Disclosure.Panel
className={`border border-th-fgd-4 border-t-0 p-4 rounded-b-md`}
>
<div>
<div className="flex justify-between pb-2">
<div className="text-th-fgd-4">Account Value</div>
<div className="text-th-fgd-1">
${simulation?.assetsVal.toFixed(2)}
</div>
</div>
<div className="flex justify-between pb-2">
<div className="text-th-fgd-4">Account Risk</div>
<div className="text-th-fgd-1">
{renderAccountRiskStatus(
simulation?.collateralRatio,
true
)}
</div>
</div>
<div className="flex justify-between pb-2">
<div className="text-th-fgd-4">Leverage</div>
<div className="text-th-fgd-1">
{simulation?.leverage.toFixed(2)}x
</div>
</div>
<div className="flex justify-between">
<div className="text-th-fgd-4">Collateral Ratio</div>
<div className="text-th-fgd-1">
{simulation?.collateralRatio * 100 < 200
? Math.floor(simulation?.collateralRatio * 100)
: '>200'}
%
</div>
</div>
{simulation?.liabsVal > 0.05 ? (
<div className="flex justify-between pt-2">
<div className="text-th-fgd-4">Borrow Value</div>
<div className="text-th-fgd-1">
${simulation?.liabsVal.toFixed(2)}
</div>
</div>
) : null}
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
) : null}
<div className={`mt-5 flex justify-center`}>
<Button onClick={handleDeposit} className="w-full">
<div className={`flex items-center justify-center`}>
@ -465,7 +267,7 @@ const DepositModal: FunctionComponent<DepositModalProps> = ({
</div>
<LinkButton
className="flex items-center mt-4 text-th-fgd-3"
onClick={() => setShowSimulation(false)}
onClick={() => setShowConfirm(false)}
>
<ChevronLeftIcon className="h-5 w-5 mr-1" />
Back

View File

@ -18,6 +18,7 @@ import {
PerpMarket,
QUOTE_INDEX,
ZERO_BN,
ZERO_I80F48,
} from '@blockworks-foundation/mango-client'
import useTradeHistory from '../hooks/useTradeHistory'
import { getAvgEntryPrice, getBreakEvenPrice } from './PerpPositionsTable'
@ -67,7 +68,6 @@ export default function MarketPosition() {
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
const selectedMarket = useMangoStore((s) => s.selectedMarket.current)
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
const selectedMarketName = marketConfig.name
const connected = useMangoStore((s) => s.wallet.connected)
const baseSymbol = marketConfig.baseSymbol
const marketName = marketConfig.name
@ -155,9 +155,25 @@ export default function MarketPosition() {
</div>
</div>
<div className={`flex justify-between pt-2 pb-2`}>
<div className="font-normal text-th-fgd-3 leading-4">
Unsettled PnL
</div>
<Tooltip
content={
<div>
Settling will update your USDC balance to reflect the PnL
amount.{' '}
<a
href="https://docs.mango.markets/mango-v3/overview#settle-pnl"
target="_blank"
rel="noopener noreferrer"
>
Learn more
</a>
</div>
}
>
<Tooltip.Content className="font-normal text-th-fgd-3 leading-4">
Unsettled PnL
</Tooltip.Content>
</Tooltip>
<div className={`flex items-center text-th-fgd-1`}>
{perpAccount
? formatUsdValue(
@ -174,14 +190,14 @@ export default function MarketPosition() {
onClick={() => handleSettlePnl(selectedMarket, perpAccount)}
className="ml-2 text-th-primary text-xs disabled:cursor-not-allowed disabled:opacity-60 disabled:hover:underline"
disabled={
perpAccount &&
+nativeI80F48ToUi(
perpAccount.getPnl(
mangoGroup.perpMarkets[marketIndex],
mangoGroupCache.priceCache[marketIndex].price
),
marketConfig.quoteDecimals
) === 0
perpAccount
? perpAccount
.getPnl(
mangoGroup.perpMarkets[marketIndex],
mangoGroupCache.priceCache[marketIndex].price
)
.eq(ZERO_I80F48)
: true
}
>
Settle
@ -262,22 +278,22 @@ export default function MarketPosition() {
>
Interest Rates
</div>
<div className={`text-th-fgd-1`}>
<span className={`text-th-green`}>
{i80f48ToPercent(
mangoGroup.getDepositRate(tokenIndex)
).toFixed(2)}
%
</span>
<span className={`text-th-fgd-4`}>{' / '}</span>
<span className={`text-th-red`}>
{i80f48ToPercent(
mangoGroup.getBorrowRate(tokenIndex)
).toFixed(2)}
%
</span>
</div>
</Tooltip>
<div className={`text-th-fgd-1`}>
<span className={`text-th-green`}>
{i80f48ToPercent(
mangoGroup.getDepositRate(tokenIndex)
).toFixed(2)}
%
</span>
<span className={`text-th-fgd-4`}>{' / '}</span>
<span className={`text-th-red`}>
{i80f48ToPercent(
mangoGroup.getBorrowRate(tokenIndex)
).toFixed(2)}
%
</span>
</div>
</div>
</div>
)

View File

@ -1,17 +1,14 @@
import React, { FunctionComponent, ReactNode } from 'react'
import React, { ReactNode } from 'react'
import Tippy from '@tippyjs/react'
import 'tippy.js/animations/scale.css'
type TooltipProps = {
content: ReactNode
className?: string
children?: ReactNode
}
const Tooltip: FunctionComponent<TooltipProps> = ({
children,
content,
className,
}) => {
const Tooltip = ({ children, content, className }: TooltipProps) => {
return (
<Tippy
animation="scale"
@ -31,4 +28,16 @@ const Tooltip: FunctionComponent<TooltipProps> = ({
)
}
const Content = ({ className, children }) => {
return (
<div
className={`cursor-help border-b border-th-fgd-3 border-dashed border-opacity-20 default-transition hover:border-th-bkg-2 ${className}`}
>
{children}
</div>
)
}
Tooltip.Content = Content
export default Tooltip

View File

@ -8,7 +8,7 @@ const TVChartContainer = dynamic(
import { useEffect, useState } from 'react'
import FloatingElement from '../components/FloatingElement'
import Orderbook from '../components/Orderbook'
import MarginInfo from './MarginInfo'
import AccountInfo from './AccountInfo'
import MarketPosition from './MarketPosition'
import TradeForm from './TradeForm'
import UserInfo from './UserInfo'
@ -26,12 +26,12 @@ export const defaultLayouts = {
{ i: 'marketTrades', x: 6, y: 1, w: 3, h: 13 },
{ i: 'marketPosition', x: 9, y: 3, w: 3, h: 13 },
{ i: 'userInfo', x: 0, y: 2, w: 9, h: 19 },
{ i: 'marginInfo', x: 9, y: 4, w: 3, h: 15 },
{ i: 'accountInfo', x: 9, y: 4, w: 3, h: 15 },
],
lg: [
{ i: 'tvChart', x: 0, y: 0, w: 8, h: 28, minW: 2 },
{ i: 'marketPosition', x: 8, y: 0, w: 4, h: 13, minW: 2 },
{ i: 'marginInfo', x: 8, y: 1, w: 4, h: 15, minW: 2 },
{ i: 'accountInfo', x: 8, y: 1, w: 4, h: 15, minW: 2 },
{ i: 'orderbook', x: 0, y: 2, w: 4, h: 17, minW: 2 },
{ i: 'tradeForm', x: 4, y: 2, w: 4, h: 17, minW: 3 },
{ i: 'marketTrades', x: 8, y: 2, w: 4, h: 17, minW: 2 },
@ -40,7 +40,7 @@ export const defaultLayouts = {
md: [
{ i: 'tvChart', x: 0, y: 0, w: 8, h: 28, minW: 2 },
{ i: 'marketPosition', x: 8, y: 0, w: 4, h: 13, minW: 2 },
{ i: 'marginInfo', x: 8, y: 1, w: 4, h: 15, minW: 2 },
{ i: 'accountInfo', x: 8, y: 1, w: 4, h: 15, minW: 2 },
{ i: 'orderbook', x: 0, y: 2, w: 4, h: 17, minW: 2 },
{ i: 'tradeForm', x: 4, y: 2, w: 4, h: 17, minW: 3 },
{ i: 'marketTrades', x: 8, y: 2, w: 4, h: 17, minW: 2 },
@ -49,7 +49,7 @@ export const defaultLayouts = {
sm: [
{ i: 'tvChart', x: 0, y: 0, w: 12, h: 25, minW: 6 },
{ i: 'marketPosition', x: 0, y: 1, w: 6, h: 15, minW: 2 },
{ i: 'marginInfo', x: 6, y: 1, w: 6, h: 15, minW: 2 },
{ i: 'accountInfo', x: 6, y: 1, w: 6, h: 15, minW: 2 },
{ i: 'tradeForm', x: 0, y: 2, w: 12, h: 13, minW: 3 },
{ i: 'orderbook', x: 0, y: 3, w: 6, h: 17, minW: 3 },
{ i: 'marketTrades', x: 6, y: 3, w: 6, h: 17, minW: 2 },
@ -58,7 +58,7 @@ export const defaultLayouts = {
xs: [
{ i: 'tvChart', x: 0, y: 0, w: 0, h: 0, minW: 6 },
{ i: 'marketPosition', x: 0, y: 1, w: 6, h: 13, minW: 2 },
{ i: 'marginInfo', x: 0, y: 2, w: 6, h: 15, minW: 2 },
{ i: 'accountInfo', x: 0, y: 2, w: 6, h: 15, minW: 2 },
{ i: 'tradeForm', x: 0, y: 3, w: 12, h: 13, minW: 3 },
{ i: 'orderbook', x: 0, y: 4, w: 6, h: 17, minW: 3 },
{ i: 'marketTrades', x: 0, y: 5, w: 6, h: 17, minW: 2 },
@ -66,7 +66,7 @@ export const defaultLayouts = {
],
}
export const GRID_LAYOUT_KEY = 'mangoSavedLayouts-3.0.4'
export const GRID_LAYOUT_KEY = 'mangoSavedLayouts-3.0.6'
const TradePageGrid = () => {
const { uiLocked } = useMangoStore((s) => s.settings)
@ -84,7 +84,7 @@ const TradePageGrid = () => {
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
if (!mounted) return null
// TODO enable savedLayouts
return (
<ResponsiveGridLayout
className="layout"
@ -107,8 +107,8 @@ const TradePageGrid = () => {
<div key="tradeForm">
<TradeForm />
</div>
<div key="marginInfo">
<MarginInfo />
<div key="accountInfo">
<AccountInfo />
</div>
<div key="userInfo">
<UserInfo />

View File

@ -4,7 +4,8 @@ import styled from '@emotion/styled'
import { Menu } from '@headlessui/react'
import Link from 'next/link'
import {
ChartBarIcon,
// ChartBarIcon,
ScaleIcon,
CurrencyDollarIcon,
ExclamationIcon,
DotsHorizontalIcon,
@ -255,7 +256,7 @@ export default function AccountOverview() {
</StyledAccountValue>
</div>
</div>
<div className="border border-th-bkg-4 p-4 rounded-lg">
{/* <div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-2 text-th-fgd-3">PNL</div>
<div className="flex items-center pb-3">
<ChartBarIcon className="flex-shrink-0 h-7 w-7 mr-1.5 text-th-primary" />
@ -265,6 +266,15 @@ export default function AccountOverview() {
)}
</StyledAccountValue>
</div>
</div> */}
<div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-2 text-th-fgd-3">Leverage</div>
<div className="flex items-center pb-3">
<ScaleIcon className="flex-shrink-0 h-7 w-7 mr-1.5 text-th-primary" />
<StyledAccountValue className="font-bold text-th-fgd-1">
{mangoAccount.getLeverage(mangoGroup, mangoCache).toFixed(2)}x
</StyledAccountValue>
</div>
</div>
<div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-2 text-th-fgd-3">Health Ratio</div>