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:
parent
c738b01382
commit
b82cf37c3d
@ -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: {
|
||||||
|
@ -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
|
||||||
|
@ -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}>
|
||||||
|
@ -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,
|
||||||
|
16
src/components/Asset/AssetSymbol.tsx
Normal file
16
src/components/Asset/AssetSymbol.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
@ -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 ',
|
||||||
|
@ -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()
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
@ -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)}
|
||||||
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -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 ' />
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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'>
|
||||||
|
@ -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(() => {
|
||||||
|
@ -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 />
|
||||||
|
36
src/hooks/perps/usePerpsMarket.ts
Normal file
36
src/hooks/perps/usePerpsMarket.ts
Normal 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))
|
||||||
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
src/types/interfaces/asset.d.ts
vendored
9
src/types/interfaces/asset.d.ts
vendored
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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'],
|
||||||
|
Loading…
Reference in New Issue
Block a user