Merge pull request #66 from blockworks-foundation/mobile-fixes
fix: mobile styling to accomodate new markets
This commit is contained in:
commit
61a6a65830
|
@ -127,7 +127,7 @@ const BalancesTable = ({ showZeroBalances = false }) => {
|
|||
const unsettledBalances = balances.filter((bal) => bal.unsettled > 0)
|
||||
|
||||
return (
|
||||
<div className={`flex flex-col pb-2 sm:pb-4 sm:pt-4`}>
|
||||
<div className={`flex flex-col pb-2 sm:pb-4`}>
|
||||
{unsettledBalances.length > 0 ? (
|
||||
<div className="border border-th-bkg-4 rounded-lg mb-6 p-4 sm:p-6">
|
||||
<div className="flex items-center justify-between pb-4">
|
||||
|
@ -167,7 +167,7 @@ const BalancesTable = ({ showZeroBalances = false }) => {
|
|||
})}
|
||||
</div>
|
||||
) : null}
|
||||
<div className={`-my-2 overflow-x-auto`}>
|
||||
<div className={`md:-my-2 md:overflow-x-auto`}>
|
||||
<div className={`align-middle inline-block min-w-full`}>
|
||||
{items.length > 0 ? (
|
||||
!isMobile ? (
|
||||
|
@ -421,19 +421,13 @@ const BalancesTable = ({ showZeroBalances = false }) => {
|
|||
) : (
|
||||
<>
|
||||
<MobileTableHeader
|
||||
headerTemplate={
|
||||
<>
|
||||
<div className="col-span-7">{t('asset')}</div>
|
||||
<div className="col-span-4 text-right">
|
||||
{t('net-balance')}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
colOneHeader={t('asset')}
|
||||
colTwoHeader={t('net-balance')}
|
||||
/>
|
||||
{items.map((balance, index) => (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<div className="col-span-11 flex items-center justify-between text-fgd-1">
|
||||
<div className="flex items-center justify-between text-fgd-1 w-full">
|
||||
<div className="flex items-center text-fgd-1">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -445,7 +439,7 @@ const BalancesTable = ({ showZeroBalances = false }) => {
|
|||
|
||||
{balance.symbol}
|
||||
</div>
|
||||
<div className="mr-1.5 text-fgd-1 text-right">
|
||||
<div className="text-fgd-1 text-right">
|
||||
{balance.net.toFixed()}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -454,37 +448,38 @@ const BalancesTable = ({ showZeroBalances = false }) => {
|
|||
index={index}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4 pb-4">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('deposits')}
|
||||
</div>
|
||||
{balance.deposits.toFixed()}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('borrows')}
|
||||
</div>
|
||||
{balance.borrows.toFixed()}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('in-orders')}
|
||||
</div>
|
||||
{balance.orders.toFixed()}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('unsettled')}
|
||||
</div>
|
||||
{balance.unsettled.toFixed()}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('value')}
|
||||
</div>
|
||||
{formatUsdValue(balance.value.toNumber())}
|
||||
</div>
|
||||
<div className="col-span-1 text-left text-th-fgd-4">
|
||||
<div className="text-left text-th-fgd-4">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('rates')}
|
||||
</div>
|
||||
|
@ -496,20 +491,25 @@ const BalancesTable = ({ showZeroBalances = false }) => {
|
|||
{balance.borrowRate.toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<Button
|
||||
className="col-span-1 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
|
||||
onClick={() => handleOpenDepositModal(balance.symbol)}
|
||||
className="text-xs pt-0 pb-0 h-8 pl-3 pr-3 w-1/2"
|
||||
onClick={() =>
|
||||
handleOpenDepositModal(balance.symbol)
|
||||
}
|
||||
>
|
||||
{t('deposit')}
|
||||
</Button>
|
||||
<Button
|
||||
className="col-span-1 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
|
||||
className="text-xs pt-0 pb-0 h-8 pl-3 pr-3 w-1/2"
|
||||
onClick={() =>
|
||||
handleOpenWithdrawModal(balance.symbol)
|
||||
}
|
||||
>
|
||||
{t('withdraw')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -9,7 +9,6 @@ import { breakpoints } from './TradePageGrid'
|
|||
import { Table, Td, Th, TrBody, TrHead } from './TableElements'
|
||||
import { formatUsdValue } from '../utils'
|
||||
import Loading from './Loading'
|
||||
|
||||
import usePerpPositions from '../hooks/usePerpPositions'
|
||||
import MarketCloseModal from './MarketCloseModal'
|
||||
import { ExpandableRow } from './TableElements'
|
||||
|
@ -17,6 +16,7 @@ import PerpSideBadge from './PerpSideBadge'
|
|||
import PnlText from './PnlText'
|
||||
import { settlePnl } from './MarketPosition'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import MobileTableHeader from './mobile/MobileTableHeader'
|
||||
|
||||
const PositionsTable = () => {
|
||||
const { t } = useTranslation('common')
|
||||
|
@ -211,7 +211,12 @@ const PositionsTable = () => {
|
|||
</tbody>
|
||||
</Table>
|
||||
) : (
|
||||
openPositions.map(
|
||||
<>
|
||||
<MobileTableHeader
|
||||
colOneHeader={t('market')}
|
||||
colTwoHeader={t('unrealized-pnl')}
|
||||
/>
|
||||
{openPositions.map(
|
||||
(
|
||||
{
|
||||
marketConfig,
|
||||
|
@ -227,7 +232,7 @@ const PositionsTable = () => {
|
|||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<>
|
||||
<div className="col-span-11 flex items-center justify-between text-fgd-1">
|
||||
<div className="flex items-center justify-between text-fgd-1 w-full">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -256,14 +261,14 @@ const PositionsTable = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<PnlText className="mr-1.5" pnl={unrealizedPnl} />
|
||||
<PnlText pnl={unrealizedPnl} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
key={`${index}`}
|
||||
index={index}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4">
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('average-entry')}
|
||||
|
@ -286,18 +291,13 @@ const PositionsTable = () => {
|
|||
? formatUsdValue(breakEvenPrice)
|
||||
: '--'}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('unrealized-pnl')}
|
||||
</div>
|
||||
<PnlText pnl={unrealizedPnl} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<div
|
||||
|
|
|
@ -87,7 +87,7 @@ export default function RecentMarketTrades() {
|
|||
) : (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<div className="col-span-11 text-left">
|
||||
<div className="flex justify-between text-left w-full">
|
||||
<div className="mb-0.5 text-fgd-1">{t('recent-trades')}</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ export const ExpandableRow = ({
|
|||
<Disclosure.Button
|
||||
className={`${
|
||||
index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-4`
|
||||
} default-transition font-normal p-4 text-th-fgd-1 w-full hover:filter hover:brightness-90 focus:outline-none ${
|
||||
} default-transition flex items-center justify-between font-normal p-4 text-th-fgd-1 w-full hover:filter hover:brightness-90 focus:outline-none ${
|
||||
rounded
|
||||
? open
|
||||
? 'rounded-b-none'
|
||||
|
@ -63,16 +63,14 @@ export const ExpandableRow = ({
|
|||
: 'rounded-none'
|
||||
}`}
|
||||
>
|
||||
<div className="grid grid-cols-12 grid-rows-1">
|
||||
{buttonTemplate}
|
||||
<div className="flex items-center justify-end">
|
||||
<div className="flex items-center justify-end pl-5">
|
||||
<ChevronDownIcon
|
||||
className={`${
|
||||
open ? 'transform rotate-180' : 'transform rotate-360'
|
||||
} default-transition h-5 flex-shrink-0 w-5 text-th-primary`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel
|
||||
className={`${
|
||||
|
@ -87,9 +85,7 @@ export const ExpandableRow = ({
|
|||
: 'rounded-none'
|
||||
}`}
|
||||
>
|
||||
<div className="grid grid-cols-2 grid-rows-1 gap-4 py-4">
|
||||
{panelTemplate}
|
||||
</div>
|
||||
<div className="py-4">{panelTemplate}</div>
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
|
@ -106,12 +102,10 @@ export const Row = ({ children, index }: RowProps) => {
|
|||
return (
|
||||
<div
|
||||
className={`${
|
||||
index % 2 === 0
|
||||
? `bg-[rgba(255,255,255,0.03)]`
|
||||
: `bg-[rgba(255,255,255,0.07)]`
|
||||
index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-4`
|
||||
} default-transition font-normal p-4 rounded-none text-th-fgd-1 w-full`}
|
||||
>
|
||||
<div className="grid grid-cols-12 grid-rows-1 gap-4">{children}</div>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import Settings from './Settings'
|
|||
const TopBar = () => {
|
||||
const { t } = useTranslation('common')
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
const [showAccountsModal, setShowAccountsModal] = useState(false)
|
||||
const [defaultMarket] = useLocalStorageState(
|
||||
DEFAULT_MARKET_KEY,
|
||||
|
@ -31,7 +30,7 @@ const TopBar = () => {
|
|||
return (
|
||||
<>
|
||||
<nav className={`bg-th-bkg-2 border-b border-th-bkg-2`}>
|
||||
<div className={`pl-2 md:px-4 lg:px-10`}>
|
||||
<div className={`px-4 lg:px-10`}>
|
||||
<div className={`flex justify-between h-14`}>
|
||||
<div className={`flex`}>
|
||||
<Link href={defaultMarket.path}>
|
||||
|
@ -46,7 +45,7 @@ const TopBar = () => {
|
|||
</div>
|
||||
</Link>
|
||||
<div
|
||||
className={`hidden md:flex md:items-center md:space-x-6 md:ml-4`}
|
||||
className={`hidden md:flex md:items-center md:space-x-4 lg:space-x-6 md:ml-4`}
|
||||
>
|
||||
<MenuItem href={defaultMarket.path}>{t('trade')}</MenuItem>
|
||||
<MenuItem href="/account">{t('account')}</MenuItem>
|
||||
|
@ -112,7 +111,7 @@ const TopBar = () => {
|
|||
</div>
|
||||
) : null}
|
||||
<div className="flex">
|
||||
<div className={`${connected ? 'pr-2 md:pr-0' : ''} pl-2`}>
|
||||
<div className="pl-2">
|
||||
<ConnectWalletButton />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -261,7 +261,7 @@ const TradeHistoryTable = ({ numTrades }: { numTrades?: number }) => {
|
|||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<>
|
||||
<div className="col-span-11 flex items-center text-fgd-1">
|
||||
<div className="flex items-center justify-between text-fgd-1 w-full">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -300,26 +300,26 @@ const TradeHistoryTable = ({ numTrades }: { numTrades?: number }) => {
|
|||
key={`${index}`}
|
||||
index={index}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('value')}
|
||||
</div>
|
||||
{formatUsdValue(trade.value)}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('liquidity')}
|
||||
</div>
|
||||
{trade.liquidity}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('fee')}
|
||||
</div>
|
||||
{formatUsdValue(trade.feeCost)}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('approximate-time')}
|
||||
</div>
|
||||
|
@ -329,7 +329,7 @@ const TradeHistoryTable = ({ numTrades }: { numTrades?: number }) => {
|
|||
)
|
||||
: t('recent')}
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
))
|
||||
|
|
|
@ -1,283 +0,0 @@
|
|||
import { useCallback, useState } from 'react'
|
||||
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
|
||||
import { InformationCircleIcon } from '@heroicons/react/outline'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
import { useBalances } from '../../hooks/useBalances'
|
||||
import { tokenPrecision } from '../../utils/index'
|
||||
import DepositModal from '../DepositModal'
|
||||
import WithdrawModal from '../WithdrawModal'
|
||||
import Button from '../Button'
|
||||
import Tooltip from '../Tooltip'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import {
|
||||
getTokenBySymbol,
|
||||
I80F48,
|
||||
PerpMarket,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
export default function AccountAssets() {
|
||||
const { t } = useTranslation('common')
|
||||
const balances = useBalances()
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
||||
const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config)
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const mangoClient = useMangoStore((s) => s.connection.client)
|
||||
const loadingMangoAccount = useMangoStore(
|
||||
(s) => s.selectedMangoAccount.initialLoad
|
||||
)
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
|
||||
const [showDepositModal, setShowDepositModal] = useState(false)
|
||||
const [showWithdrawModal, setShowWithdrawModal] = useState(false)
|
||||
const [withdrawSymbol, setWithdrawSymbol] = useState('')
|
||||
const [depositSymbol, setDepositSymbol] = useState('')
|
||||
|
||||
const handleCloseDeposit = useCallback(() => {
|
||||
setShowDepositModal(false)
|
||||
}, [])
|
||||
|
||||
const handleCloseWithdraw = useCallback(() => {
|
||||
setShowWithdrawModal(false)
|
||||
}, [])
|
||||
|
||||
const handleShowWithdraw = (symbol) => {
|
||||
setWithdrawSymbol(symbol)
|
||||
setShowWithdrawModal(true)
|
||||
}
|
||||
|
||||
const handleShowDeposit = (symbol) => {
|
||||
setDepositSymbol(symbol)
|
||||
setShowDepositModal(true)
|
||||
}
|
||||
|
||||
async function handleSettleAllTrades() {
|
||||
const markets: Array<Market | PerpMarket> = Object.values(
|
||||
useMangoStore.getState().selectedMangoGroup.markets
|
||||
)
|
||||
const mangoAccount = useMangoStore.getState().selectedMangoAccount.current
|
||||
const mangoGroup = useMangoStore.getState().selectedMangoGroup.current
|
||||
const wallet = useMangoStore.getState().wallet.current
|
||||
const spotMarkets = markets.filter(
|
||||
(mkt) => mkt instanceof Market
|
||||
) as Market[]
|
||||
|
||||
try {
|
||||
await mangoClient.settleAll(mangoGroup, mangoAccount, spotMarkets, wallet)
|
||||
actions.reloadMangoAccount()
|
||||
} catch (e) {
|
||||
if (e.message === 'No unsettled funds') {
|
||||
notify({
|
||||
title: t('no-unsettled'),
|
||||
type: 'error',
|
||||
})
|
||||
} else {
|
||||
notify({
|
||||
title: t('settle-error'),
|
||||
description: e.message,
|
||||
txid: e.txid,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mangoAccount ? (
|
||||
<>
|
||||
<div className="sm:flex sm:items-center sm:justify-between pb-2">
|
||||
<div className="pb-2 sm:pb-0 text-th-fgd-1 text-lg">
|
||||
{t('your-assets')}
|
||||
</div>
|
||||
{balances.length > 0 ? (
|
||||
<div className="border border-th-green flex items-center justify-between p-2 rounded">
|
||||
<div className="pr-4 text-xs text-th-fgd-3">
|
||||
{t('total-assets')}:
|
||||
</div>
|
||||
<span>
|
||||
$ {mangoAccount.getAssetsVal(mangoGroup, mangoCache).toFixed(2)}
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
{balances.length > 0 &&
|
||||
balances.find(({ unsettled }) => unsettled > 0) ? (
|
||||
<div
|
||||
className={`flex items-center justify-between px-6 py-4 my-2 rounded-md bg-th-bkg-1`}
|
||||
>
|
||||
<div className="flex items-center text-fgd-1 font-semibold pr-4">
|
||||
You have unsettled funds
|
||||
<Tooltip content="Use the Settle All button to move unsettled funds to your deposits.">
|
||||
<div>
|
||||
<InformationCircleIcon
|
||||
className={`h-5 w-5 ml-2 text-th-primary cursor-help`}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Button onClick={handleSettleAllTrades}>{t('settle-all')}</Button>
|
||||
</div>
|
||||
) : null}
|
||||
{mangoGroup && balances.length > 0 ? (
|
||||
<div className={`flex flex-col py-4`}>
|
||||
<div className={`-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8`}>
|
||||
<div
|
||||
className={`align-middle inline-block min-w-full sm:px-6 lg:px-8`}
|
||||
>
|
||||
<Table className="min-w-full divide-y divide-th-bkg-2">
|
||||
<Thead>
|
||||
<Tr className="text-th-fgd-3 text-xs">
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
{t('asset')}
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Available
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
{t('in-orders')}
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
{t('unsettled')}
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
{t('value')}
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
{t('interest')} APY
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{balances.map((bal, i) => {
|
||||
const token = getTokenBySymbol(groupConfig, bal.symbol)
|
||||
const tokenIndex = mangoGroup.getTokenIndex(token.mintKey)
|
||||
|
||||
return (
|
||||
<Tr
|
||||
key={tokenIndex}
|
||||
className={`border-b border-th-bkg-3
|
||||
${i % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
|
||||
`}
|
||||
>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
width="20"
|
||||
height="20"
|
||||
src={`/assets/icons/${bal.symbol.toLowerCase()}.svg`}
|
||||
className={`mr-2.5`}
|
||||
/>
|
||||
<div>{bal.symbol}</div>
|
||||
</div>
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{bal.deposits.toFixed(tokenPrecision[bal.symbol])}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{bal.orders.toFixed(tokenPrecision[bal.symbol])}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{bal.unsettled.toFixed(tokenPrecision[bal.symbol])}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
$
|
||||
{(
|
||||
(bal.deposits.toNumber() +
|
||||
bal.orders +
|
||||
bal.unsettled) *
|
||||
mangoGroup
|
||||
.getPrice(tokenIndex, mangoCache)
|
||||
.toNumber()
|
||||
).toFixed(2)}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
<span className={`text-th-green`}>
|
||||
{mangoGroup
|
||||
.getDepositRate(tokenIndex)
|
||||
.mul(I80F48.fromNumber(100))
|
||||
.toFixed(2)}
|
||||
%
|
||||
</span>
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-3 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
<div className={`flex justify-end`}>
|
||||
<Button
|
||||
onClick={() => handleShowDeposit(bal.symbol)}
|
||||
className="text-xs pt-0 pb-0 h-8 pl-3 pr-3"
|
||||
disabled={!connected || loadingMangoAccount}
|
||||
>
|
||||
<span>{t('deposit')}</span>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleShowWithdraw(bal.symbol)}
|
||||
className="ml-3 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
|
||||
disabled={!connected || loadingMangoAccount}
|
||||
>
|
||||
<span>{t('withdraw')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</Td>
|
||||
</Tr>
|
||||
)
|
||||
})}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={`w-full text-center py-6 bg-th-bkg-1 text-th-fgd-3 rounded-md`}
|
||||
>
|
||||
No assets found.
|
||||
</div>
|
||||
)}
|
||||
{showDepositModal && (
|
||||
<DepositModal
|
||||
isOpen={showDepositModal}
|
||||
onClose={handleCloseDeposit}
|
||||
tokenSymbol={depositSymbol}
|
||||
/>
|
||||
)}
|
||||
{showWithdrawModal && (
|
||||
<WithdrawModal
|
||||
isOpen={showWithdrawModal}
|
||||
onClose={handleCloseWithdraw}
|
||||
tokenSymbol={withdrawSymbol}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : null
|
||||
}
|
|
@ -167,14 +167,8 @@ export default function AccountBorrows() {
|
|||
) : (
|
||||
<>
|
||||
<MobileTableHeader
|
||||
headerTemplate={
|
||||
<>
|
||||
<div className="col-span-7">{t('asset')}</div>
|
||||
<div className="col-span-4 text-right">
|
||||
{t('balance')}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
colOneHeader={t('asset')}
|
||||
colTwoHeader={t('balance')}
|
||||
/>
|
||||
{balances
|
||||
.filter((assets) => assets.borrows.gt(ZERO_I80F48))
|
||||
|
@ -189,8 +183,8 @@ export default function AccountBorrows() {
|
|||
return (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<>
|
||||
<div className="col-span-7 flex items-center text-fgd-1">
|
||||
<div className="flex items-center justify-between text-fgd-1 w-full">
|
||||
<div className="flex items-center text-fgd-1">
|
||||
<img
|
||||
alt=""
|
||||
width="20"
|
||||
|
@ -201,18 +195,19 @@ export default function AccountBorrows() {
|
|||
|
||||
{asset.symbol}
|
||||
</div>
|
||||
<div className="col-span-4 text-fgd-1 text-right">
|
||||
<div className="text-fgd-1 text-right">
|
||||
{asset.borrows.toFixed(
|
||||
tokenPrecision[asset.symbol]
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
}
|
||||
key={`${asset.symbol}${i}`}
|
||||
index={i}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4 pb-4">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('value')}
|
||||
</div>
|
||||
|
@ -227,7 +222,7 @@ export default function AccountBorrows() {
|
|||
.toNumber()
|
||||
)}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('borrow-rate')} (APR)
|
||||
</div>
|
||||
|
@ -240,8 +235,9 @@ export default function AccountBorrows() {
|
|||
%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-span-1">
|
||||
<div className="flex space-x-4">
|
||||
<Button
|
||||
onClick={() =>
|
||||
handleShowDeposit(asset.symbol)
|
||||
|
@ -251,8 +247,6 @@ export default function AccountBorrows() {
|
|||
>
|
||||
{t('deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="col-span-1">
|
||||
<Button
|
||||
onClick={() =>
|
||||
handleShowBorrow(asset.symbol)
|
||||
|
@ -382,22 +376,16 @@ export default function AccountBorrows() {
|
|||
) : (
|
||||
<>
|
||||
<MobileTableHeader
|
||||
headerTemplate={
|
||||
<>
|
||||
<div className="col-span-5">{t('asset')}</div>
|
||||
<div className="col-span-6 text-right">
|
||||
{t('borrow-rate')} (APR)
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
colOneHeader={t('asset')}
|
||||
colTwoHeader={`${t('borrow-rate')} (APR)`}
|
||||
/>
|
||||
{mangoConfig.tokens.map((token, i) => {
|
||||
const tokenIndex = mangoGroup.getTokenIndex(token.mintKey)
|
||||
return (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<>
|
||||
<div className="col-span-7 flex items-center text-fgd-1">
|
||||
<div className="flex items-center justify-between text-fgd-1 w-full">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
width="20"
|
||||
|
@ -408,7 +396,7 @@ export default function AccountBorrows() {
|
|||
|
||||
{token.symbol}
|
||||
</div>
|
||||
<div className="col-span-4 text-fgd-1 text-right">
|
||||
<div className="text-fgd-1 text-right">
|
||||
<span className={`text-th-red`}>
|
||||
{i80f48ToPercent(
|
||||
mangoGroup.getBorrowRate(tokenIndex)
|
||||
|
@ -416,13 +404,13 @@ export default function AccountBorrows() {
|
|||
%
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
}
|
||||
key={`${token.symbol}${i}`}
|
||||
index={i}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('price')}
|
||||
</div>
|
||||
|
@ -432,7 +420,7 @@ export default function AccountBorrows() {
|
|||
.toNumber()
|
||||
)}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('max-borrow')}
|
||||
</div>
|
||||
|
@ -451,7 +439,7 @@ export default function AccountBorrows() {
|
|||
tokenPrecision[token.symbol],
|
||||
})}
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('liquidity')}
|
||||
</div>
|
||||
|
@ -466,8 +454,8 @@ export default function AccountBorrows() {
|
|||
tokenPrecision[token.symbol],
|
||||
})}
|
||||
</div>
|
||||
<div className="col-span-1" />
|
||||
<div className="col-span-1">
|
||||
<div className="" />
|
||||
<div className="">
|
||||
<Button
|
||||
onClick={() => handleShowBorrow(token.symbol)}
|
||||
className="text-xs pt-0 pb-0 h-8 w-full"
|
||||
|
@ -476,7 +464,7 @@ export default function AccountBorrows() {
|
|||
{t('borrow')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { getTokenBySymbol } from '@blockworks-foundation/mango-client'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
import Loading from '../Loading'
|
||||
import Select from '../Select'
|
||||
import { Table, Td, Th, TrBody, TrHead } from '../TableElements'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
@ -9,6 +8,10 @@ import { isEmpty } from 'lodash'
|
|||
import usePagination from '../../hooks/usePagination'
|
||||
import { roundToDecimal } from '../../utils/'
|
||||
import Pagination from '../Pagination'
|
||||
import { useViewport } from '../../hooks/useViewport'
|
||||
import { breakpoints } from '../TradePageGrid'
|
||||
import { ExpandableRow } from '../TableElements'
|
||||
import MobileTableHeader from '../mobile/MobileTableHeader'
|
||||
|
||||
interface InterestStats {
|
||||
[key: string]: {
|
||||
|
@ -22,11 +25,9 @@ const AccountInterest = () => {
|
|||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config)
|
||||
const [interestStats, setInterestStats] = useState<any>([])
|
||||
const [hourlyInterestStats, setHourlyInterestStats] = useState<any>({
|
||||
USDC: [],
|
||||
})
|
||||
const [hourlyInterestStats, setHourlyInterestStats] = useState<any>({})
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [selectedAsset, setSelectedAsset] = useState<string>('USDC')
|
||||
const [selectedAsset, setSelectedAsset] = useState<string>('')
|
||||
const {
|
||||
paginated,
|
||||
setData,
|
||||
|
@ -37,13 +38,17 @@ const AccountInterest = () => {
|
|||
firstPage,
|
||||
lastPage,
|
||||
} = usePagination(hourlyInterestStats[selectedAsset])
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.md : false
|
||||
|
||||
const mangoAccountPk = useMemo(() => {
|
||||
return mangoAccount.publicKey.toString()
|
||||
}, [mangoAccount])
|
||||
|
||||
const token = useMemo(() => {
|
||||
if (selectedAsset) {
|
||||
return getTokenBySymbol(groupConfig, selectedAsset)
|
||||
}
|
||||
}, [selectedAsset])
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -52,6 +57,12 @@ const AccountInterest = () => {
|
|||
}
|
||||
}, [selectedAsset, hourlyInterestStats])
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedAsset && Object.keys(hourlyInterestStats).length > 0) {
|
||||
setSelectedAsset(Object.keys(hourlyInterestStats)[0])
|
||||
}
|
||||
}, [hourlyInterestStats])
|
||||
|
||||
useEffect(() => {
|
||||
const fetchInterestStats = async () => {
|
||||
const response = await fetch(
|
||||
|
@ -104,11 +115,10 @@ const AccountInterest = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="pb-3.5 text-th-fgd-1 text-base">
|
||||
{t('interest-earned')}
|
||||
</div>
|
||||
<div className="pb-4 text-th-fgd-1 text-lg">{t('interest-earned')}</div>
|
||||
{mangoAccount ? (
|
||||
<div>
|
||||
{!isMobile ? (
|
||||
<Table>
|
||||
<thead>
|
||||
<TrHead>
|
||||
|
@ -122,7 +132,7 @@ const AccountInterest = () => {
|
|||
{interestStats.length === 0 ? (
|
||||
<TrBody index={0}>
|
||||
<td colSpan={4}>
|
||||
<div className="flex">
|
||||
<div className="bg-th-bkg-3 flex rounded-md text-th-fgd-3">
|
||||
<div className="mx-auto py-4">{t('no-interest')}</div>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -153,7 +163,8 @@ const AccountInterest = () => {
|
|||
{symbol}
|
||||
</Td>
|
||||
<Td>
|
||||
{stats.total_borrow_interest.toFixed(decimals)} {symbol}
|
||||
{stats.total_borrow_interest.toFixed(decimals)}{' '}
|
||||
{symbol}
|
||||
</Td>
|
||||
<Td>
|
||||
{(
|
||||
|
@ -168,14 +179,78 @@ const AccountInterest = () => {
|
|||
)}
|
||||
</tbody>
|
||||
</Table>
|
||||
) : interestStats.length === 0 ? (
|
||||
<div className="bg-th-bkg-3 flex rounded-md text-th-fgd-3">
|
||||
<div className="mx-auto py-4">{t('no-interest')}</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<MobileTableHeader
|
||||
colOneHeader={t('token')}
|
||||
colTwoHeader={t('net')}
|
||||
/>
|
||||
{interestStats.map(([symbol, stats], index) => {
|
||||
const decimals = getTokenBySymbol(groupConfig, symbol).decimals
|
||||
return (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<div className="flex items-center justify-between text-fgd-1 w-full">
|
||||
<div className="flex items-center text-fgd-1">
|
||||
<img
|
||||
alt=""
|
||||
width="20"
|
||||
height="20"
|
||||
src={`/assets/icons/${symbol.toLowerCase()}.svg`}
|
||||
className={`mr-2.5`}
|
||||
/>
|
||||
|
||||
{symbol}
|
||||
</div>
|
||||
<div className="text-fgd-1 text-right">
|
||||
{(
|
||||
stats.total_deposit_interest -
|
||||
stats.total_borrow_interest
|
||||
).toFixed(decimals)}{' '}
|
||||
{symbol}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
key={`${symbol}${index}`}
|
||||
index={index}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('total-deposit-interest')}
|
||||
</div>
|
||||
{stats.total_deposit_interest.toFixed(decimals)}{' '}
|
||||
{symbol}
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('total-borrow-interest')}
|
||||
</div>
|
||||
{stats.total_borrow_interest.toFixed(decimals)}{' '}
|
||||
{symbol}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
<>
|
||||
{!isEmpty(hourlyInterestStats) && !loading ? (
|
||||
<>
|
||||
<div className="flex items-center justify-between my-4 w-full">
|
||||
<div className="flex items-center justify-between pb-4 pt-6 w-full">
|
||||
<div className="text-th-fgd-1 text-lg">{t('history')}</div>
|
||||
<Select
|
||||
value={selectedAsset}
|
||||
onChange={(a) => setSelectedAsset(a)}
|
||||
className="w-24 sm:hidden"
|
||||
className="w-24 md:hidden"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
{Object.keys(hourlyInterestStats).map((token: string) => (
|
||||
|
@ -191,7 +266,7 @@ const AccountInterest = () => {
|
|||
))}
|
||||
</div>
|
||||
</Select>
|
||||
<div className="hidden sm:flex pb-4 sm:pb-0">
|
||||
<div className="hidden md:flex pb-4 sm:pb-0">
|
||||
{Object.keys(hourlyInterestStats).map((token: string) => (
|
||||
<div
|
||||
className={`px-2 py-1 ml-2 rounded-md cursor-pointer default-transition bg-th-bkg-3
|
||||
|
@ -226,8 +301,10 @@ const AccountInterest = () => {
|
|||
return (
|
||||
<TrBody index={index} key={stat.time}>
|
||||
<Td>
|
||||
{date.toLocaleDateString()}{' '}
|
||||
<div>{date.toLocaleDateString()}</div>
|
||||
<div className="text-xs text-th-fgd-3">
|
||||
{date.toLocaleTimeString()}
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
{stat.borrow_interest > 0
|
||||
|
@ -261,10 +338,10 @@ const AccountInterest = () => {
|
|||
</div>
|
||||
</>
|
||||
) : loading ? (
|
||||
<div className="flex justify-center my-8">
|
||||
<div>
|
||||
<Loading />
|
||||
</div>
|
||||
<div className="pt-8 space-y-2">
|
||||
<div className="animate-pulse bg-th-bkg-3 h-12 rounded-md w-full" />
|
||||
<div className="animate-pulse bg-th-bkg-3 h-12 rounded-md w-full" />
|
||||
<div className="animate-pulse bg-th-bkg-3 h-12 rounded-md w-full" />
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
|
|
|
@ -209,7 +209,7 @@ export default function AccountOverview() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between pb-4 sm:pb-0">
|
||||
<div className="flex justify-between pb-4 md:pb-6">
|
||||
<div className="text-th-fgd-1 text-lg">Balances</div>
|
||||
<Switch
|
||||
checked={showZeroBalances}
|
||||
|
|
|
@ -37,7 +37,7 @@ const BottomBar = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-th-bkg-4 default-transition grid grid-cols-4 grid-rows-1 py-2.5">
|
||||
<div className="bg-th-bkg-1 default-transition grid grid-cols-4 grid-rows-1 py-2.5">
|
||||
<div
|
||||
className="col-span-1 cursor-pointer default-transition flex flex-col items-center text-th-fgd-3 hover:text-th-primary"
|
||||
onClick={() => setShowMarketsModal(true)}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
type MobileTableHeaderProps = {
|
||||
headerTemplate: React.ReactNode
|
||||
colOneHeader: string
|
||||
colTwoHeader: string
|
||||
}
|
||||
|
||||
const MobileTableHeader = ({ headerTemplate }: MobileTableHeaderProps) => {
|
||||
const MobileTableHeader = ({
|
||||
colOneHeader,
|
||||
colTwoHeader,
|
||||
}: MobileTableHeaderProps) => {
|
||||
return (
|
||||
<div className="grid grid-cols-12 grid-rows-1 gap-4 pb-2 px-3 text-xs">
|
||||
{headerTemplate}
|
||||
<div className="flex justify-between pb-2 pl-4 pr-14 text-th-fgd-3 text-xs">
|
||||
<div>{colOneHeader}</div>
|
||||
<div>{colTwoHeader}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ const MobileTradePage = () => {
|
|||
<Swipeable index={viewIndex} onChangeIndex={handleChangeViewIndex}>
|
||||
<div>
|
||||
<div className="bg-th-bkg-2 grid grid-cols-12 grid-rows-1 gap-4 mb-2 px-2 py-3 rounded-lg">
|
||||
<div className="col-span-7">
|
||||
<div className="col-span-7 pt-2">
|
||||
<AdvancedTradeForm />
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function StatsAssets({ latestStats, stats }) {
|
|||
<Select
|
||||
value={selectedAsset}
|
||||
onChange={(a) => setSelectedAsset(a)}
|
||||
className="w-24 sm:hidden"
|
||||
className="w-24 md:hidden"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
{latestStats.map((stat) => (
|
||||
|
@ -42,7 +42,7 @@ export default function StatsAssets({ latestStats, stats }) {
|
|||
))}
|
||||
</div>
|
||||
</Select>
|
||||
<div className="hidden sm:flex pb-4 sm:pb-0">
|
||||
<div className="hidden md:flex pb-4 sm:pb-0">
|
||||
{latestStats.map((stat) => (
|
||||
<div
|
||||
className={`px-2 py-1 ml-2 rounded-md cursor-pointer default-transition bg-th-bkg-3
|
||||
|
|
|
@ -6,6 +6,7 @@ import Chart from '../Chart'
|
|||
import BN from 'bn.js'
|
||||
import { tokenPrecision } from '../../utils'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Select from '../Select'
|
||||
|
||||
function calculateFundingRate(
|
||||
oldestLongFunding,
|
||||
|
@ -82,7 +83,7 @@ export default function StatsPerps({ perpStats }) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col-reverse sm:flex-row sm:items-center sm:justify-between mb-4 w-full">
|
||||
<div className="flex items-center justify-between mb-4 w-full">
|
||||
<div className="flex items-center text-xl text-th-fgd-1">
|
||||
<img
|
||||
width="24"
|
||||
|
@ -94,7 +95,26 @@ export default function StatsPerps({ perpStats }) {
|
|||
/>
|
||||
{selectedAsset.split(/-|\//)[0]} {t('perpetual-futures')}
|
||||
</div>
|
||||
<div className="flex mb-4 sm:mb-0 space-x-2">
|
||||
<Select
|
||||
value={selectedAsset}
|
||||
onChange={(a) => setSelectedAsset(a)}
|
||||
className="flex-shrink-0 ml-4 w-36 md:hidden"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
{marketConfigs.map((market) => (
|
||||
<Select.Option
|
||||
key={market.name}
|
||||
value={market.name}
|
||||
className={`bg-th-bkg-1 relative rounded-md w-full px-3 py-3 cursor-pointer default-transition flex hover:bg-th-bkg-3 focus:outline-none`}
|
||||
>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
{market.name}
|
||||
</div>
|
||||
</Select.Option>
|
||||
))}
|
||||
</div>
|
||||
</Select>
|
||||
<div className="hidden md:flex space-x-2">
|
||||
{marketConfigs.map((market) => (
|
||||
<div
|
||||
className={`bg-th-bkg-3 cursor-pointer default-transition px-2 py-1 rounded-md text-center w-full whitespace-nowrap
|
||||
|
@ -107,7 +127,7 @@ export default function StatsPerps({ perpStats }) {
|
|||
onClick={() => setSelectedAsset(market.name)}
|
||||
key={market.name as string}
|
||||
>
|
||||
{market.name}
|
||||
{market.name.slice(0, -5)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -345,8 +345,8 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
// latestStats.length > 0 ? (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
<div className="col-span-11">
|
||||
<div className="col-span-11 flex items-center pb-4 text-fgd-1">
|
||||
<div className="grid grid-cols-12 grid-rows-2 sm:grid-rows-1 gap-2 text-left sm:text-right w-full">
|
||||
<div className="col-span-12 sm:col-span-6 flex items-center text-fgd-1">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -360,27 +360,25 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
{stat.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-11 grid-rows-1 gap-4">
|
||||
<div className="col-span-6 text-left">
|
||||
<div className="col-span-6 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('total-deposits')}
|
||||
</div>
|
||||
{formatNumberString(stat.totalDeposits, 0)}
|
||||
</div>
|
||||
<div className="col-span-5 text-left">
|
||||
<div className="col-span-6 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('total-borrows')}
|
||||
</div>
|
||||
{formatNumberString(stat.totalBorrows, 0)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
key={stat.name}
|
||||
index={index}
|
||||
panelTemplate={
|
||||
<>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="grid grid-cols-2 grid-flow-row gap-4">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('deposit-rate')}
|
||||
</div>
|
||||
|
@ -389,7 +387,7 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
%
|
||||
</span>
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('borrow-rate')}
|
||||
</div>
|
||||
|
@ -397,7 +395,7 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
{formatNumberString(stat.borrowInterest.toNumber(), 2)}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
{t('utilization')}
|
||||
</div>
|
||||
|
@ -407,7 +405,7 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
)}
|
||||
%
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
@ -419,8 +417,8 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
{stats.length > 1
|
||||
? latestStats.map((stat, index) => (
|
||||
<Row key={stat.name} index={index}>
|
||||
<div className="col-span-12">
|
||||
<div className="col-span-12 flex items-center pb-4 text-fgd-1">
|
||||
<div className="grid grid-cols-12 grid-rows-2 sm:grid-rows-1 gap-2 text-left sm:text-right">
|
||||
<div className="col-span-12 sm:col-span-3 flex items-center text-fgd-1">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -434,28 +432,17 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
{stat.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 grid-rows-1 gap-4">
|
||||
<div className="col-span-4 text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
24h
|
||||
</div>
|
||||
<div className="col-span-4 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">24h</div>
|
||||
{getAverageStats(stats, 1, stat.name, 'depositIndex')}
|
||||
</div>
|
||||
<div className="col-span-4 text-left">
|
||||
<div className="col-span-4 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">7d</div>
|
||||
{getAverageStats(stats, 7, stat.name, 'depositIndex')}
|
||||
</div>
|
||||
<div className="col-span-4 text-left">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
30d
|
||||
</div>
|
||||
{getAverageStats(
|
||||
stats,
|
||||
30,
|
||||
stat.name,
|
||||
'depositIndex'
|
||||
)}
|
||||
</div>
|
||||
<div className="col-span-4 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">30d</div>
|
||||
{getAverageStats(stats, 30, stat.name, 'depositIndex')}
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
|
@ -468,8 +455,8 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
{stats.length > 1
|
||||
? latestStats.map((stat, index) => (
|
||||
<Row key={stat.name} index={index}>
|
||||
<div className="col-span-12">
|
||||
<div className="col-span-12 flex items-center pb-4 text-fgd-1">
|
||||
<div className="grid grid-cols-12 grid-rows-2 sm:grid-rows-1 gap-2 text-left sm:text-right">
|
||||
<div className="col-span-12 sm:col-span-3 flex items-center text-fgd-1">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -483,21 +470,19 @@ export default function StatsTotals({ latestStats, stats }) {
|
|||
{stat.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 grid-rows-1 gap-4">
|
||||
<div className="col-span-4 text-left">
|
||||
<div className="col-span-4 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">24h</div>
|
||||
{getAverageStats(stats, 1, stat.name, 'borrowIndex')}
|
||||
</div>
|
||||
<div className="col-span-4 text-left">
|
||||
<div className="col-span-4 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">7d</div>
|
||||
{getAverageStats(stats, 7, stat.name, 'borrowIndex')}
|
||||
</div>
|
||||
<div className="col-span-4 text-left">
|
||||
<div className="col-span-4 sm:col-span-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">30d</div>
|
||||
{getAverageStats(stats, 30, stat.name, 'borrowIndex')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
))
|
||||
: null}
|
||||
|
|
|
@ -738,7 +738,7 @@ export default function AdvancedTradeForm({
|
|||
unit="%"
|
||||
values={
|
||||
isMobile
|
||||
? ['10', '25', '50', '75']
|
||||
? ['10', '25', '50', '100']
|
||||
: ['10', '25', '50', '75', '100']
|
||||
}
|
||||
/>
|
||||
|
@ -871,9 +871,10 @@ export default function AdvancedTradeForm({
|
|||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex text-xs text-th-fgd-4 px-6 mt-2.5 justify-center">
|
||||
Maker fee: {(makerFee * 100).toFixed(2)}% | Taker fee:{' '}
|
||||
{takerFee * 100}%
|
||||
<div className="flex flex-col md:flex-row text-xs text-th-fgd-4 px-6 mt-2.5 items-center justify-center">
|
||||
<div>Maker fee: {(makerFee * 100).toFixed(2)}% </div>
|
||||
<span className="hidden md:block md:px-1">|</span>
|
||||
<div> Taker fee: {takerFee * 100}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,22 +18,22 @@ const OrderSideTabs: FunctionComponent<OrderSideTabsProps> = ({
|
|||
const { t } = useTranslation('common')
|
||||
const market = useMangoStore((s) => s.selectedMarket.current)
|
||||
return (
|
||||
<div className={`border-b border-th-fgd-4 mb-3 relative -mt-2.5`}>
|
||||
<div className={`md:border-b md:border-th-fgd-4 mb-3 relative -mt-2.5`}>
|
||||
<div
|
||||
className={`absolute ${
|
||||
className={`absolute hidden md:block ${
|
||||
side === 'buy'
|
||||
? 'bg-th-green translate-x-0'
|
||||
: 'bg-th-red translate-x-full'
|
||||
} bottom-[-1px] default-transition left-0 h-0.5 transform w-1/2`}
|
||||
/>
|
||||
<nav className="-mb-px flex" aria-label="Tabs">
|
||||
<nav className="-mb-px flex space-x-2" aria-label="Tabs">
|
||||
<button
|
||||
onClick={() => onChange('buy')}
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center pb-2 md:py-2 relative text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center py-1.5 md:py-2 relative text-sm md:text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
${
|
||||
side === 'buy'
|
||||
? `text-th-green`
|
||||
: `text-th-fgd-4 hover:text-th-green`
|
||||
? `border border-th-green md:border-0 text-th-green`
|
||||
: `border border-th-fgd-4 md:border-0 text-th-fgd-4 hover:border-th-green hover:text-th-green`
|
||||
}
|
||||
`}
|
||||
>
|
||||
|
@ -41,11 +41,11 @@ const OrderSideTabs: FunctionComponent<OrderSideTabsProps> = ({
|
|||
</button>
|
||||
<button
|
||||
onClick={() => onChange('sell')}
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center pb-2 md:py-2 relative text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center py-1.5 md:py-2 relative text-sm md:text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
${
|
||||
side === 'sell'
|
||||
? `text-th-red`
|
||||
: `text-th-fgd-4 hover:text-th-red`
|
||||
? `border border-th-red md:border-0 text-th-red`
|
||||
: `border border-th-fgd-4 md:border-0 text-th-fgd-4 hover:border-th-red hover:text-th-red`
|
||||
}
|
||||
`}
|
||||
>
|
||||
|
|
|
@ -20,13 +20,13 @@ import AccountNameModal from '../components/AccountNameModal'
|
|||
import Button from '../components/Button'
|
||||
import EmptyState from '../components/EmptyState'
|
||||
import Loading from '../components/Loading'
|
||||
import SwipeableTabs from '../components/mobile/SwipeableTabs'
|
||||
import Swipeable from '../components/mobile/Swipeable'
|
||||
import Tabs from '../components/Tabs'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
import { breakpoints } from '../components/TradePageGrid'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Select from '../components/Select'
|
||||
|
||||
export async function getServerSideProps({ locale }) {
|
||||
return {
|
||||
|
@ -37,17 +37,7 @@ export async function getServerSideProps({ locale }) {
|
|||
}
|
||||
}
|
||||
|
||||
const TABS = [
|
||||
'Portfolio',
|
||||
// 'Assets',
|
||||
// 'Borrows',
|
||||
// 'Stats',
|
||||
// 'Positions',
|
||||
'Orders',
|
||||
'Trade History',
|
||||
'Interest',
|
||||
'Funding',
|
||||
]
|
||||
const TABS = ['Portfolio', 'Orders', 'Trade History', 'Interest', 'Funding']
|
||||
|
||||
export default function Account() {
|
||||
const { t } = useTranslation('common')
|
||||
|
@ -155,11 +145,18 @@ export default function Account() {
|
|||
tabs={TABS}
|
||||
/>
|
||||
) : (
|
||||
<SwipeableTabs
|
||||
onChange={handleChangeViewIndex}
|
||||
tabs={TABS}
|
||||
tabIndex={viewIndex}
|
||||
/>
|
||||
<div className="pb-2 pt-3">
|
||||
<Select
|
||||
value={TABS[viewIndex]}
|
||||
onChange={(e) => handleChangeViewIndex(e)}
|
||||
>
|
||||
{TABS.map((tab, index) => (
|
||||
<Select.Option key={index + tab} value={index}>
|
||||
{tab}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
) : null}
|
||||
<div className="bg-th-bkg-2 p-4 sm:p-6 rounded-lg">
|
||||
|
@ -180,6 +177,12 @@ export default function Account() {
|
|||
<div>
|
||||
<AccountHistory />
|
||||
</div>
|
||||
<div>
|
||||
<AccountInterest />
|
||||
</div>
|
||||
<div>
|
||||
<AccountFunding />
|
||||
</div>
|
||||
</Swipeable>
|
||||
)
|
||||
) : connected ? (
|
||||
|
|
|
@ -38,10 +38,14 @@ export default function Borrow() {
|
|||
<TopBar />
|
||||
<PageBodyContainer>
|
||||
<div className="pt-8 pb-3 sm:pb-4 md:pt-10">
|
||||
{connected ? (
|
||||
<>
|
||||
<h1 className={`mb-1 text-th-fgd-1 text-2xl font-semibold`}>
|
||||
{t('borrow-funds')}
|
||||
</h1>
|
||||
<p>{t('borrow-notification')}</p>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="bg-th-bkg-2 overflow-none p-4 sm:p-6 rounded-lg">
|
||||
{selectedMangoAccount ? (
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"health-ratio": "Health Ratio",
|
||||
"hide-all": "Hide all from Nav",
|
||||
"high": "High",
|
||||
"history": "History",
|
||||
"hourly-borrow-interest": "Hourly Borrow Interest",
|
||||
"hourly-deposit-interest": "Hourly Deposit Interest",
|
||||
"hourly-funding": "Hourly Funding",
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
"health-ratio": "Relación de salud",
|
||||
"hide-all": "Ocultar todo de Nav",
|
||||
"high": "Alta",
|
||||
"history": "La Historia",
|
||||
"hourly-borrow-interest": "Préstamo prestado por hora",
|
||||
"hourly-deposit-interest": "Interés por depósito por hora",
|
||||
"hourly-funding": "Financiamiento por hora",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"health-ratio": "健康比率",
|
||||
"hide-all": "在导航栏中隐藏全部",
|
||||
"high": "高",
|
||||
"history": "历史",
|
||||
"hourly-borrow-interest": "1小时借贷利息",
|
||||
"hourly-deposit-interest": "1小时存款利息",
|
||||
"hourly-funding": "1小时资金费",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"health-ratio": "健康比率",
|
||||
"hide-all": "在導航欄中隱藏全部",
|
||||
"high": "高",
|
||||
"history": "歷史",
|
||||
"hourly-borrow-interest": "1小時借貸利息",
|
||||
"hourly-deposit-interest": "1小時存款利息",
|
||||
"hourly-funding": "1小時資金費",
|
||||
|
|
Loading…
Reference in New Issue