Add usePerpsMarket hook and adjust routing (#680)

* Add usePerpsMarket hook and adjust routing

* fix: enable 7 links in the header

---------

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>
This commit is contained in:
Bob van der Helm 2023-12-06 15:29:48 +01:00 committed by GitHub
parent c738b01382
commit b82cf37c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 201 additions and 47 deletions

View File

@ -1,5 +1,5 @@
import classNames from 'classnames' import classNames from 'classnames'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import useAccountBalancesColumns from 'components/Account/AccountBalancesTable/Columns/useAccountBalancesColumns' import useAccountBalancesColumns from 'components/Account/AccountBalancesTable/Columns/useAccountBalancesColumns'
import useAccountBalanceData from 'components/Account/AccountBalancesTable/useAccountBalanceData' import useAccountBalanceData from 'components/Account/AccountBalancesTable/useAccountBalanceData'
@ -22,6 +22,7 @@ interface Props {
} }
export default function AccountBalancesTable(props: Props) { export default function AccountBalancesTable(props: Props) {
const [searchParams] = useSearchParams()
const { account, lendingData, borrowingData, tableBodyClassName, hideCard } = props const { account, lendingData, borrowingData, tableBodyClassName, hideCard } = props
const currentAccount = useCurrentAccount() const currentAccount = useCurrentAccount()
const navigate = useNavigate() const navigate = useNavigate()
@ -55,7 +56,7 @@ export default function AccountBalancesTable(props: Props) {
color='tertiary' color='tertiary'
onClick={() => { onClick={() => {
if (currentAccount?.id !== account.id) { if (currentAccount?.id !== account.id) {
navigate(getRoute(getPage(pathname), address, account.id)) navigate(getRoute(getPage(pathname), searchParams, address, account.id))
} }
useStore.setState({ useStore.setState({
focusComponent: { focusComponent: {

View File

@ -1,5 +1,5 @@
import { useCallback, useEffect } from 'react' import { useCallback, useEffect } from 'react'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import AccountFundFullPage from 'components/Account/AccountFund/AccountFundFullPage' import AccountFundFullPage from 'components/Account/AccountFund/AccountFundFullPage'
import FullOverlayContent from 'components/FullOverlayContent' import FullOverlayContent from 'components/FullOverlayContent'
@ -14,6 +14,7 @@ export default function AccountCreateFirst() {
const address = useStore((s) => s.address) const address = useStore((s) => s.address)
const createAccount = useStore((s) => s.createAccount) const createAccount = useStore((s) => s.createAccount)
const [isCreating, setIsCreating] = useToggle(false) const [isCreating, setIsCreating] = useToggle(false)
const [searchParams] = useSearchParams()
useEffect(() => { useEffect(() => {
if (!address) useStore.setState({ focusComponent: { component: <WalletSelect /> } }) if (!address) useStore.setState({ focusComponent: { component: <WalletSelect /> } })
@ -24,7 +25,7 @@ export default function AccountCreateFirst() {
const accountId = await createAccount('default') const accountId = await createAccount('default')
setIsCreating(false) setIsCreating(false)
if (accountId) { if (accountId) {
navigate(getRoute(getPage(pathname), address, accountId)) navigate(getRoute(getPage(pathname), searchParams, address, accountId))
useStore.setState({ useStore.setState({
focusComponent: { focusComponent: {
component: <AccountFundFullPage />, component: <AccountFundFullPage />,
@ -34,7 +35,7 @@ export default function AccountCreateFirst() {
}, },
}) })
} }
}, [createAccount, navigate, pathname, address, setIsCreating]) }, [setIsCreating, createAccount, navigate, pathname, searchParams, address])
return ( return (
<FullOverlayContent <FullOverlayContent

View File

@ -1,6 +1,6 @@
import classNames from 'classnames' import classNames from 'classnames'
import { useEffect } from 'react' import { useEffect } from 'react'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import AccountStats from 'components/Account/AccountList/AccountStats' import AccountStats from 'components/Account/AccountList/AccountStats'
import Card from 'components/Card' import Card from 'components/Card'
@ -28,6 +28,7 @@ export default function AccountList(props: Props) {
const currentAccountId = useAccountId() const currentAccountId = useAccountId()
const address = useStore((s) => s.address) const address = useStore((s) => s.address)
const { data: accountIds } = useAccountIds(address, true, true) const { data: accountIds } = useAccountIds(address, true, true)
const [searchParams] = useSearchParams()
useEffect(() => { useEffect(() => {
if (!currentAccountId) return if (!currentAccountId) return
@ -54,7 +55,7 @@ export default function AccountList(props: Props) {
onClick={() => { onClick={() => {
if (isActive) return if (isActive) return
useStore.setState({ accountDeleteModal: null }) useStore.setState({ accountDeleteModal: null })
navigate(getRoute(getPage(pathname), address, accountId)) navigate(getRoute(getPage(pathname), searchParams, address, accountId))
}} }}
title={ title={
<div className={accountCardHeaderClasses} role={!isActive ? 'button' : undefined}> <div className={accountCardHeaderClasses} role={!isActive ? 'button' : undefined}>

View File

@ -1,6 +1,6 @@
import classNames from 'classnames' import classNames from 'classnames'
import { useCallback } from 'react' import { useCallback } from 'react'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import AccountCreateFirst from 'components/Account/AccountCreateFirst' import AccountCreateFirst from 'components/Account/AccountCreateFirst'
import AccountFund from 'components/Account/AccountFund/AccountFundFullPage' import AccountFund from 'components/Account/AccountFund/AccountFundFullPage'
@ -33,6 +33,7 @@ export default function AccountMenuContent() {
const address = useStore((s) => s.address) const address = useStore((s) => s.address)
const { data: accountIds } = useAccountIds(address, true, true) const { data: accountIds } = useAccountIds(address, true, true)
const accountId = useAccountId() const accountId = useAccountId()
const [searchParams] = useSearchParams()
const createAccount = useStore((s) => s.createAccount) const createAccount = useStore((s) => s.createAccount)
const baseCurrency = useStore((s) => s.baseCurrency) const baseCurrency = useStore((s) => s.baseCurrency)
@ -63,7 +64,7 @@ export default function AccountMenuContent() {
setIsCreating(false) setIsCreating(false)
if (accountId) { if (accountId) {
navigate(getRoute(getPage(pathname), address, accountId)) navigate(getRoute(getPage(pathname), searchParams, address, accountId))
if (lendAssets) enableAutoLendAccountId(accountId) if (lendAssets) enableAutoLendAccountId(accountId)
useStore.setState({ useStore.setState({
focusComponent: { focusComponent: {
@ -80,6 +81,7 @@ export default function AccountMenuContent() {
createAccount, createAccount,
navigate, navigate,
pathname, pathname,
searchParams,
address, address,
lendAssets, lendAssets,
enableAutoLendAccountId, enableAutoLendAccountId,

View File

@ -0,0 +1,16 @@
import Text from 'components/Text'
interface Props {
symbol: string
}
export default function AssetSymbol(props: Props) {
return (
<Text
size='xs'
tag='span'
className='rounded-sm bg-white/10 text-white/50 px-[6px] py-[2px] h-5'
>
{props.symbol}
</Text>
)
}

View File

@ -1,5 +1,5 @@
import classNames from 'classnames' import classNames from 'classnames'
import { NavLink, useParams } from 'react-router-dom' import { NavLink, useParams, useSearchParams } from 'react-router-dom'
import useAccountId from 'hooks/useAccountId' import useAccountId from 'hooks/useAccountId'
import { getRoute } from 'utils/route' import { getRoute } from 'utils/route'
@ -15,13 +15,14 @@ interface Props {
export default function Tab(props: Props) { export default function Tab(props: Props) {
const accountId = useAccountId() const accountId = useAccountId()
const { address } = useParams() const { address } = useParams()
const [searchParams] = useSearchParams()
return ( return (
<div className='relative w-full'> <div className='relative w-full'>
{props.tabs.map((tab, index) => ( {props.tabs.map((tab, index) => (
<NavLink <NavLink
key={tab.page} key={tab.page}
to={getRoute(tab.page, address, accountId)} to={getRoute(tab.page, searchParams, address, accountId)}
className={classNames( className={classNames(
props.activeTabIdx === index ? underlineClasses : 'text-white/40', props.activeTabIdx === index ? underlineClasses : 'text-white/40',
'relative mr-8 text-xl ', 'relative mr-8 text-xl ',

View File

@ -1,5 +1,5 @@
import { useCallback, useMemo } from 'react' import { useCallback, useMemo } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom' import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom'
import AssetBalanceRow from 'components/Asset/AssetBalanceRow' import AssetBalanceRow from 'components/Asset/AssetBalanceRow'
import { ArrowRight, ExclamationMarkCircled } from 'components/Icons' import { ArrowRight, ExclamationMarkCircled } from 'components/Icons'
@ -30,6 +30,7 @@ function AccountDeleteModal(props: Props) {
const { pathname } = useLocation() const { pathname } = useLocation()
const { address } = useParams() const { address } = useParams()
const { debts, vaults, id: accountId } = modal || {} const { debts, vaults, id: accountId } = modal || {}
const [searchParams] = useSearchParams()
const closeDeleteAccountModal = useCallback(() => { const closeDeleteAccountModal = useCallback(() => {
useStore.setState({ accountDeleteModal: null }) useStore.setState({ accountDeleteModal: null })
@ -38,9 +39,18 @@ function AccountDeleteModal(props: Props) {
const deleteAccountHandler = useCallback(() => { const deleteAccountHandler = useCallback(() => {
const options = { accountId: modal.id, lends: modal.lends } const options = { accountId: modal.id, lends: modal.lends }
deleteAccount(options) deleteAccount(options)
navigate(getRoute(getPage(pathname), address)) navigate(getRoute(getPage(pathname), searchParams, address))
closeDeleteAccountModal() closeDeleteAccountModal()
}, [modal, deleteAccount, navigate, pathname, address, closeDeleteAccountModal]) }, [
modal.id,
modal.lends,
deleteAccount,
navigate,
pathname,
searchParams,
address,
closeDeleteAccountModal,
])
const depositsAndLends = useMemo( const depositsAndLends = useMemo(
() => combineBNCoins([...modal.deposits, ...modal.lends]), () => combineBNCoins([...modal.deposits, ...modal.lends]),
@ -58,7 +68,7 @@ function AccountDeleteModal(props: Props) {
text: 'Repay Debts', text: 'Repay Debts',
icon: <ArrowRight />, icon: <ArrowRight />,
onClick: () => { onClick: () => {
navigate(getRoute('borrow', address, accountId)) navigate(getRoute('borrow', searchParams, address, accountId))
closeDeleteAccountModal() closeDeleteAccountModal()
}, },
}} }}
@ -75,7 +85,7 @@ function AccountDeleteModal(props: Props) {
text: 'Close Positions', text: 'Close Positions',
icon: <ArrowRight />, icon: <ArrowRight />,
onClick: () => { onClick: () => {
navigate(getRoute('farm', address, accountId)) navigate(getRoute('farm', searchParams, address, accountId))
closeDeleteAccountModal() closeDeleteAccountModal()
}, },
}} }}

View File

@ -1,6 +1,7 @@
import { useShuttle } from '@delphi-labs/shuttle-react' import { useShuttle } from '@delphi-labs/shuttle-react'
import classNames from 'classnames' import classNames from 'classnames'
import { useMemo } from 'react' import { useMemo } from 'react'
import { useSearchParams } from 'react-router-dom'
import Button from 'components/Button' import Button from 'components/Button'
import { menuTree } from 'components/Header/DesktopHeader' import { menuTree } from 'components/Header/DesktopHeader'
@ -18,7 +19,7 @@ export default function DesktopNavigation() {
const walletId = (recentWallet?.providerId as WalletID) ?? WalletID.Keplr const walletId = (recentWallet?.providerId as WalletID) ?? WalletID.Keplr
const address = useStore((s) => s.address) const address = useStore((s) => s.address)
const accountId = useAccountId() const accountId = useAccountId()
const [searchParams] = useSearchParams()
const focusComponent = useStore((s) => s.focusComponent) const focusComponent = useStore((s) => s.focusComponent)
const menu = useMemo(() => menuTree(walletId), [walletId]) const menu = useMemo(() => menuTree(walletId), [walletId])
@ -36,7 +37,7 @@ export default function DesktopNavigation() {
: 'flex flex-1 items-center relative z-50', : 'flex flex-1 items-center relative z-50',
)} )}
> >
<NavLink href={getRoute('trade', address, accountId)}> <NavLink href={getRoute('trade', searchParams, address, accountId)}>
<span className='block w-10 h-10'> <span className='block w-10 h-10'>
<Logo className='text-white' /> <Logo className='text-white' />
</span> </span>
@ -47,7 +48,9 @@ export default function DesktopNavigation() {
<NavLink <NavLink
key={index} key={index}
href={ href={
item.externalUrl ? item.externalUrl : getRoute(item.pages[0], address, accountId) item.externalUrl
? item.externalUrl
: getRoute(item.pages[0], searchParams, address, accountId)
} }
isActive={getIsActive(item.pages)} isActive={getIsActive(item.pages)}
className={`@nav-${index}/navigation:inline-block hidden whitespace-nowrap`} className={`@nav-${index}/navigation:inline-block hidden whitespace-nowrap`}
@ -84,7 +87,7 @@ export default function DesktopNavigation() {
href={ href={
item.externalUrl item.externalUrl
? item.externalUrl ? item.externalUrl
: getRoute(item.pages[0], address, accountId) : getRoute(item.pages[0], searchParams, address, accountId)
} }
onClick={() => setShowMenu(false)} onClick={() => setShowMenu(false)}
isActive={getIsActive(item.pages)} isActive={getIsActive(item.pages)}

View File

@ -1,19 +1,52 @@
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
import AssetSymbol from 'components/Asset/AssetSymbol'
import Card from 'components/Card' import Card from 'components/Card'
import DisplayCurrency from 'components/DisplayCurrency'
import Divider from 'components/Divider' import Divider from 'components/Divider'
import { FormattedNumber } from 'components/FormattedNumber'
import Loading from 'components/Loading'
import Text from 'components/Text' import Text from 'components/Text'
import usePerpsMarket from 'hooks/perps/usePerpsMarket'
import usePrice from 'hooks/usePrice'
import { BNCoin } from 'types/classes/BNCoin'
export function PerpsInfo() { export function PerpsInfo() {
const { data: market } = usePerpsMarket()
const assetPrice = usePrice(market?.asset.denom || '')
const items = useMemo( const items = useMemo(
() => [ () => [
<Text key='item1'>$6,735</Text>, ...(!assetPrice.isZero()
<InfoItem key='item2' label='Label' item={<Text size='sm'>Value</Text>} />, ? [<DisplayCurrency key='price' coin={BNCoin.fromDenomAndBigNumber('usd', assetPrice)} />]
<InfoItem key='item3' label='Label' item={<Text size='sm'>Value</Text>} />, : [<Loading key='price' className='w-14 h-4' />]),
<InfoItem key='item4' label='Label' item={<Text size='sm'>Value</Text>} />, <InfoItem
<InfoItem key='item5' label='Label' item={<Text size='sm'>Value</Text>} />, key='openInterestLong'
label='Open Interest (L)'
item={<InterestItem market={market} type='long' />}
/>,
<InfoItem
key='openInterestShort'
label='Open Interest (S)'
item={<InterestItem market={market} type='short' />}
/>,
<InfoItem
key='fundingRate'
label='Funding rate'
item={
market ? (
<FormattedNumber
className='text-sm inline'
amount={market.fundingRate.toNumber()}
options={{ minDecimals: 6, maxDecimals: 6, suffix: '%' }}
/>
) : (
<Loading />
)
}
/>,
], ],
[], [assetPrice, market],
) )
return ( return (
@ -45,3 +78,22 @@ function InfoItem(props: InfoItemProps) {
</div> </div>
) )
} }
interface InterestItemProps {
market: PerpsMarket | null
type: 'long' | 'short'
}
function InterestItem(props: InterestItemProps) {
if (!props.market) return <Loading />
return (
<div className='flex gap-1 items-center'>
<FormattedNumber
className='text-sm inline'
amount={props.market.openInterest[props.type].toNumber()}
options={{ decimals: props.market.asset.decimals }}
/>
<AssetSymbol symbol={props.market.asset.symbol} />
</div>
)
}

View File

@ -1,4 +1,4 @@
import { NavLink, useParams } from 'react-router-dom' import { NavLink, useParams, useSearchParams } from 'react-router-dom'
import { ArrowRight } from 'components/Icons' import { ArrowRight } from 'components/Icons'
import Text from 'components/Text' import Text from 'components/Text'
@ -12,10 +12,11 @@ interface Props {
export default function PortfolioAccountPageHeader(props: Props) { export default function PortfolioAccountPageHeader(props: Props) {
const { address } = useParams() const { address } = useParams()
const selectedAccountId = useAccountId() const selectedAccountId = useAccountId()
const [searchParams] = useSearchParams()
return ( return (
<div className='flex items-center w-full gap-2 pt-2 pb-6 border-b border-white/20'> <div className='flex items-center w-full gap-2 pt-2 pb-6 border-b border-white/20'>
<NavLink to={getRoute('portfolio', address, selectedAccountId)}> <NavLink to={getRoute('portfolio', searchParams, address, selectedAccountId)}>
<Text className='text-white/40'>Portfolio</Text> <Text className='text-white/40'>Portfolio</Text>
</NavLink> </NavLink>
<ArrowRight className='h-3 text-white/60 ' /> <ArrowRight className='h-3 text-white/60 ' />

View File

@ -1,6 +1,6 @@
import classNames from 'classnames' import classNames from 'classnames'
import { ReactNode, useMemo } from 'react' import { ReactNode, useMemo } from 'react'
import { NavLink, useParams } from 'react-router-dom' import { NavLink, useParams, useSearchParams } from 'react-router-dom'
import { FormattedNumber } from 'components/FormattedNumber' import { FormattedNumber } from 'components/FormattedNumber'
import Loading from 'components/Loading' import Loading from 'components/Loading'
@ -36,6 +36,7 @@ export default function PortfolioCard(props: Props) {
const { allAssets: lendingAssets } = useLendingMarketAssetsTableData() const { allAssets: lendingAssets } = useLendingMarketAssetsTableData()
const { data } = useBorrowMarketAssetsTableData(false) const { data } = useBorrowMarketAssetsTableData(false)
const { data: hlsStrategies } = useHLSStakingAssets() const { data: hlsStrategies } = useHLSStakingAssets()
const [searchParams] = useSearchParams()
const borrowAssets = useMemo(() => data?.allAssets || [], [data]) const borrowAssets = useMemo(() => data?.allAssets || [], [data])
const [reduceMotion] = useLocalStorage<boolean>( const [reduceMotion] = useLocalStorage<boolean>(
@ -111,7 +112,12 @@ export default function PortfolioCard(props: Props) {
return ( return (
<NavLink <NavLink
to={getRoute(`portfolio/${props.accountId}` as Page, urlAddress, currentAccountId)} to={getRoute(
`portfolio/${props.accountId}` as Page,
searchParams,
urlAddress,
currentAccountId,
)}
className={classNames('w-full hover:bg-white/5', !reduceMotion && 'transition-all')} className={classNames('w-full hover:bg-white/5', !reduceMotion && 'transition-all')}
> >
<Skeleton <Skeleton

View File

@ -5,8 +5,8 @@ import DisplayCurrency from 'components/DisplayCurrency'
import { FormattedNumber } from 'components/FormattedNumber' import { FormattedNumber } from 'components/FormattedNumber'
import Loading from 'components/Loading' import Loading from 'components/Loading'
import Text from 'components/Text' import Text from 'components/Text'
import { DataFeed, PAIR_SEPARATOR } from 'components/Trade/TradeChart/DataFeed'
import { disabledFeatures, enabledFeatures, overrides } from 'components/Trade/TradeChart/constants' import { disabledFeatures, enabledFeatures, overrides } from 'components/Trade/TradeChart/constants'
import { DataFeed, PAIR_SEPARATOR } from 'components/Trade/TradeChart/DataFeed'
import { BN_ZERO } from 'constants/math' import { BN_ZERO } from 'constants/math'
import usePrices from 'hooks/usePrices' import usePrices from 'hooks/usePrices'
import useStore from 'store' import useStore from 'store'
@ -156,7 +156,7 @@ export const TVChartContainer = (props: Props) => {
</div> </div>
} }
contentClassName='px-0.5 pb-0.5 h-full' contentClassName='px-0.5 pb-0.5 h-full'
className='min-h-[55vh]' className='min-h-[55vh] h-full'
> >
<div ref={chartContainerRef} className='h-full overflow-hidden rounded-b-base' /> <div ref={chartContainerRef} className='h-full overflow-hidden rounded-b-base' />
</Card> </Card>

View File

@ -1,4 +1,5 @@
import AssetImage from 'components/Asset/AssetImage' import AssetImage from 'components/Asset/AssetImage'
import AssetSymbol from 'components/Asset/AssetSymbol'
import DisplayCurrency from 'components/DisplayCurrency' import DisplayCurrency from 'components/DisplayCurrency'
import { FormattedNumber } from 'components/FormattedNumber' import { FormattedNumber } from 'components/FormattedNumber'
import { StarFilled, StarOutlined } from 'components/Icons' import { StarFilled, StarOutlined } from 'components/Icons'
@ -53,9 +54,7 @@ export default function AssetItem(props: Props) {
<Text size='sm' className='h-5 leading-5 text-left truncate '> <Text size='sm' className='h-5 leading-5 text-left truncate '>
{asset.name} {asset.name}
</Text> </Text>
<div className='rounded-sm bg-white/20 px-[6px] py-[2px] h-5 leading-5 '> <AssetSymbol symbol={asset.symbol} />
<Text size='xs'>{asset.symbol}</Text>
</div>
</div> </div>
{props.balances.length > 0 && ( {props.balances.length > 0 && (
<div className='flex gap-1'> <div className='flex gap-1'>

View File

@ -1,10 +1,10 @@
import { useShuttle } from '@delphi-labs/shuttle-react' import { useShuttle } from '@delphi-labs/shuttle-react'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import classNames from 'classnames' import classNames from 'classnames'
import { useCallback, useEffect, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import useClipboard from 'react-use-clipboard'
import { resolvePrimaryDomainByAddress } from 'ibc-domains-sdk' import { resolvePrimaryDomainByAddress } from 'ibc-domains-sdk'
import { useCallback, useEffect, useState } from 'react'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import useClipboard from 'react-use-clipboard'
import Button from 'components/Button' import Button from 'components/Button'
import { CircularProgress } from 'components/CircularProgress' import { CircularProgress } from 'components/CircularProgress'
@ -44,6 +44,7 @@ export default function WalletConnectedButton() {
const { data: icnsData, isLoading: isLoadingICNS } = useICNSDomain(address) const { data: icnsData, isLoading: isLoadingICNS } = useICNSDomain(address)
const navigate = useNavigate() const navigate = useNavigate()
const { pathname } = useLocation() const { pathname } = useLocation()
const [searchParams] = useSearchParams()
// --------------- // ---------------
// LOCAL STATE // LOCAL STATE
@ -87,7 +88,7 @@ export default function WalletConnectedButton() {
}) })
} }
navigate(getRoute(getPage(pathname))) navigate(getRoute(getPage(pathname), searchParams))
} }
useEffect(() => { useEffect(() => {

View File

@ -1,5 +1,5 @@
import { Suspense, useEffect, useMemo } from 'react' import { Suspense, useEffect, useMemo } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom' import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom'
import AccountCreateFirst from 'components/Account/AccountCreateFirst' import AccountCreateFirst from 'components/Account/AccountCreateFirst'
import { CircularProgress } from 'components/CircularProgress' import { CircularProgress } from 'components/CircularProgress'
@ -28,6 +28,8 @@ function FetchLoading() {
function Content() { function Content() {
const address = useStore((s) => s.address) const address = useStore((s) => s.address)
const [searchParams] = useSearchParams()
const { address: urlAddress } = useParams() const { address: urlAddress } = useParams()
const urlAccountId = useAccountId() const urlAccountId = useAccountId()
const navigate = useNavigate() const navigate = useNavigate()
@ -48,7 +50,7 @@ function Content() {
useEffect(() => { useEffect(() => {
const page = getPage(pathname) const page = getPage(pathname)
if (page === 'portfolio' && urlAddress && urlAddress !== address) { if (page === 'portfolio' && urlAddress && urlAddress !== address) {
navigate(getRoute(page, urlAddress as string)) navigate(getRoute(page, searchParams, urlAddress as string))
useStore.setState({ balances: walletBalances, focusComponent: null }) useStore.setState({ balances: walletBalances, focusComponent: null })
return return
} }
@ -60,7 +62,7 @@ function Content() {
) { ) {
const currentAccountIsHLS = urlAccountId && !accountIds.includes(urlAccountId) const currentAccountIsHLS = urlAccountId && !accountIds.includes(urlAccountId)
const currentAccount = currentAccountIsHLS || !urlAccountId ? accountIds[0] : urlAccountId const currentAccount = currentAccountIsHLS || !urlAccountId ? accountIds[0] : urlAccountId
navigate(getRoute(page, address, currentAccount)) navigate(getRoute(page, searchParams, address, currentAccount))
useStore.setState({ balances: walletBalances, focusComponent: null }) useStore.setState({ balances: walletBalances, focusComponent: null })
} }
}, [ }, [
@ -72,6 +74,7 @@ function Content() {
walletBalances, walletBalances,
urlAddress, urlAddress,
urlAccountId, urlAccountId,
searchParams,
]) ])
if (isLoadingAccounts || isLoadingBalances) return <FetchLoading /> if (isLoadingAccounts || isLoadingBalances) return <FetchLoading />

View File

@ -0,0 +1,36 @@
import { useSearchParams } from 'react-router-dom'
import useSWR from 'swr'
import { ASSETS } from 'constants/assets'
import { getAssetBySymbol } from 'utils/assets'
import { BN } from 'utils/helpers'
export default function usePerpsMarket() {
const [searchParams] = useSearchParams()
const perpsMarket = searchParams.get('perpsMarket') || ASSETS[0].symbol
const asset = getAssetBySymbol(perpsMarket)
return useSWR(
`perpsMarket/${perpsMarket}`,
async () => {
await delay(3000)
if (!asset) return null
return {
asset,
fundingRate: BN(0.001432),
openInterest: {
long: BN(92901203),
short: BN(129891203),
},
} as PerpsMarket
},
{
fallbackData: null,
},
)
}
function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms))
}

View File

@ -1,4 +1,4 @@
import { useNavigate, useParams } from 'react-router-dom' import { useNavigate, useParams, useSearchParams } from 'react-router-dom'
import MigrationBanner from 'components/MigrationBanner' import MigrationBanner from 'components/MigrationBanner'
import Balances from 'components/Portfolio/Account/Balances' import Balances from 'components/Portfolio/Account/Balances'
@ -12,9 +12,10 @@ export default function PortfolioAccountPage() {
const selectedAccountId = useAccountId() const selectedAccountId = useAccountId()
const { address, accountId } = useParams() const { address, accountId } = useParams()
const navigate = useNavigate() const navigate = useNavigate()
const [searchParams] = useSearchParams()
if (!accountId) { if (!accountId) {
navigate(getRoute('portfolio', address, selectedAccountId)) navigate(getRoute('portfolio', searchParams, address, selectedAccountId))
return null return null
} }

View File

@ -144,3 +144,12 @@ interface StakingApr {
unbondingDelay: number unbondingDelay: number
unbondingPeriod: number unbondingPeriod: number
} }
interface PerpsMarket {
asset: Asset
fundingRate: BigNumber
openInterest: {
long: BigNumber
short: BigNumber
}
}

View File

@ -1,4 +1,9 @@
export function getRoute(page: Page, address?: string, accountId?: string | null) { export function getRoute(
page: Page,
searchParams: URLSearchParams,
address?: string,
accountId?: string | null,
) {
let nextUrl = '' let nextUrl = ''
if (address) { if (address) {
@ -9,10 +14,13 @@ export function getRoute(page: Page, address?: string, accountId?: string | null
let url = new URL(nextUrl, 'https://app.marsprotocol.io') let url = new URL(nextUrl, 'https://app.marsprotocol.io')
Array.from(searchParams?.entries() || []).map(([key, value]) =>
url.searchParams.append(key, value),
)
if (accountId) { if (accountId) {
url.searchParams.append('accountId', accountId)
} else {
url.searchParams.delete('accountId') url.searchParams.delete('accountId')
url.searchParams.append('accountId', accountId)
} }
return url.pathname + url.search return url.pathname + url.search

View File

@ -41,12 +41,14 @@ module.exports = {
'@nav-3/navigation:inline-block', '@nav-3/navigation:inline-block',
'@nav-4/navigation:inline-block', '@nav-4/navigation:inline-block',
'@nav-5/navigation:inline-block', '@nav-5/navigation:inline-block',
'@nav-6/navigation:inline-block',
'@nav-0/navigation:hidden', '@nav-0/navigation:hidden',
'@nav-1/navigation:hidden', '@nav-1/navigation:hidden',
'@nav-2/navigation:hidden', '@nav-2/navigation:hidden',
'@nav-3/navigation:hidden', '@nav-3/navigation:hidden',
'@nav-4/navigation:hidden', '@nav-4/navigation:hidden',
'@nav-5/navigation:hidden', '@nav-5/navigation:hidden',
'@nav-6/navigation:hidden',
], ],
theme: { theme: {
extend: { extend: {
@ -141,6 +143,7 @@ module.exports = {
'nav-3': '400px', 'nav-3': '400px',
'nav-4': '500px', 'nav-4': '500px',
'nav-5': '600px', 'nav-5': '600px',
'nav-6': '650px',
}, },
fontFamily: { fontFamily: {
sans: ['Inter', 'sans-serif'], sans: ['Inter', 'sans-serif'],