Merge pull request #543 from mars-protocol/develop

This commit is contained in:
Linkie Link 2023-10-14 18:30:33 +02:00 committed by GitHub
commit 7272b1eee0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 244 additions and 62 deletions

View File

@ -14,15 +14,28 @@ jest.mock('hooks/useHealthComputer', () =>
jest.mock('components/Account/AccountBalancesTable', () => jest.fn(() => null))
const mockedUseCurrentAccount = useCurrentAccount as jest.Mock
const mockedAccount = { id: '1', deposits: [], lends: [], debts: [], vaults: [] }
const mockedAccounts = [
{ id: '1', deposits: [], lends: [], debts: [], vaults: [] },
{ id: '2', deposits: [], lends: [], debts: [], vaults: [] },
]
jest.mock('hooks/useAccountId', () => jest.fn(() => '1'))
jest.mock('hooks/useAccounts', () => jest.fn(() => [mockedAccount]))
jest.mock('hooks/useAccounts', () =>
jest.fn(() => ({
data: mockedAccounts,
})),
)
jest.mock('hooks/useAccountIds', () =>
jest.fn(() => ({
data: ['1', '2'],
})),
)
jest.mock('hooks/useCurrentAccount', () => jest.fn(() => mockedAccounts[0]))
describe('<AccountDetails />', () => {
beforeAll(() => {
useStore.setState({
address: 'walletAddress',
accounts: [mockedAccount],
accounts: mockedAccounts,
})
})
@ -31,7 +44,7 @@ describe('<AccountDetails />', () => {
})
it('renders account details WHEN account is selected', () => {
mockedUseCurrentAccount.mockReturnValue(mockedAccount)
mockedUseCurrentAccount.mockReturnValue(mockedAccounts)
render(<AccountDetails />)
const container = screen.queryByTestId('account-details')

View File

@ -1,7 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
productionBrowserSourceMaps: true,
reactStrictMode: true,
images: {
domains: [
@ -26,6 +25,31 @@ const nextConfig = {
},
]
},
async headers() {
return [
{
source: '/(.*)?',
headers: [
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin',
},
{
key: 'Pragma',
value: 'no-cache',
},
{
key: 'Expires',
value: new Date().toString(),
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
],
},
]
},
async rewrites() {
return [
{

View File

@ -5,8 +5,8 @@ export default async function getAccountIds(
address?: string,
previousResults?: string[],
): Promise<string[]> {
try {
if (!address) return []
try {
const accountNftQueryClient = await getAccountNftQueryClient()
const lastItem = previousResults && previousResults.at(-1)

View File

@ -17,6 +17,7 @@ import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
import { REDUCE_MOTION_KEY } from 'constants/localStore'
import { ORACLE_DENOM } from 'constants/oracle'
import useAccountId from 'hooks/useAccountId'
import useAccountIds from 'hooks/useAccountIds'
import useAccounts from 'hooks/useAccounts'
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
import useCurrentAccount from 'hooks/useCurrentAccount'
@ -34,12 +35,15 @@ import {
export default function AccountDetailsController() {
const address = useStore((s) => s.address)
const { isLoading } = useAccounts(address)
const { data: accounts, isLoading } = useAccounts(address)
const { data: accountIds } = useAccountIds(address, false)
const accountId = useAccountId()
const account = useCurrentAccount()
const focusComponent = useStore((s) => s.focusComponent)
if (!address || focusComponent) return null
const focusComponent = useStore((s) => s.focusComponent)
const isOwnAccount = accountId && accountIds?.includes(accountId)
if (!address || focusComponent || !isOwnAccount) return null
if ((isLoading && accountId && !focusComponent) || !account) return <Skeleton />

View File

@ -1,6 +1,6 @@
import classNames from 'classnames'
import { useEffect } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import AccountStats from 'components/Account/AccountList/AccountStats'
import Card from 'components/Card'
@ -26,7 +26,7 @@ export default function AccountList(props: Props) {
const navigate = useNavigate()
const { pathname } = useLocation()
const currentAccountId = useAccountId()
const { address } = useParams()
const address = useStore((s) => s.address)
const { data: accountIds } = useAccountIds(address)
useEffect(() => {
@ -37,7 +37,7 @@ export default function AccountList(props: Props) {
}
}, [currentAccountId])
if (!accountIds?.length) return null
if (!accountIds || !accountIds.length) return null
return (
<div className='flex flex-wrap w-full p-4'>

View File

@ -1,6 +1,6 @@
import classNames from 'classnames'
import { useCallback } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import AccountCreateFirst from 'components/Account/AccountCreateFirst'
import AccountFund from 'components/Account/AccountFund/AccountFundFullPage'
@ -30,7 +30,7 @@ const ACCOUNT_MENU_BUTTON_ID = 'account-menu-button'
export default function AccountMenuContent() {
const navigate = useNavigate()
const { pathname } = useLocation()
const { address } = useParams()
const address = useStore((s) => s.address)
const { data: accountIds } = useAccountIds(address)
const accountId = useAccountId()
@ -42,8 +42,9 @@ export default function AccountMenuContent() {
const [lendAssets] = useLocalStorage<boolean>(LEND_ASSETS_KEY, DEFAULT_SETTINGS.lendAssets)
const { enableAutoLendAccountId } = useAutoLend()
const hasCreditAccounts = !!accountIds.length
const isAccountSelected = isNumber(accountId)
const hasCreditAccounts = !!accountIds?.length
const isAccountSelected =
hasCreditAccounts && accountId && isNumber(accountId) && accountIds.includes(accountId)
const checkHasFunds = useCallback(() => {
return (

View File

@ -23,7 +23,7 @@ export default function ActionButton(props: ButtonProps) {
if (!address) return <WalletConnectButton {...defaultProps} />
if (accountIds.length === 0) {
if (accountIds && accountIds.length === 0) {
return (
<Button
onClick={handleCreateAccountClick}

View File

@ -28,7 +28,7 @@ export default function FarmIntro() {
leftIcon={<PlusSquared />}
onClick={(e) => {
e.preventDefault()
window.open(DocURL.ROVER_INTRO_URL, '_blank')
window.open(DocURL.FARM_INTRO_URL, '_blank')
}}
color='secondary'
/>

View File

@ -8,7 +8,8 @@ const underlineClasses =
'relative before:absolute before:h-[2px] before:-bottom-1 before:left-0 before:right-0 before:gradient-active-tab'
interface Props {
isFarm?: boolean
tabs: Tab[]
activeTabIdx: number
}
export default function Tab(props: Props) {
@ -17,24 +18,18 @@ export default function Tab(props: Props) {
return (
<div className='relative w-full'>
{props.tabs.map((tab, index) => (
<NavLink
to={getRoute('lend', address, accountId)}
key={tab.page}
to={getRoute(tab.page, address, accountId)}
className={classNames(
props.isFarm ? 'text-white/40' : underlineClasses,
props.activeTabIdx === index ? underlineClasses : 'text-white/40',
'relative mr-8 text-xl ',
)}
>
Lend
</NavLink>
<NavLink
to={getRoute('farm', address, accountId)}
className={classNames(
!props.isFarm ? 'text-white/40' : underlineClasses,
'relative text-xl',
)}
>
Farm
{tab.name}
</NavLink>
))}
</div>
)
}

View File

@ -9,12 +9,14 @@ import Settings from 'components/Settings'
import Wallet from 'components/Wallet'
import useAccountId from 'hooks/useAccountId'
import useStore from 'store'
import { ENABLE_HLS } from 'utils/constants'
export const menuTree: { pages: Page[]; label: string }[] = [
{ pages: ['trade'], label: 'Trade' },
{ pages: ['lend', 'farm'], label: 'Earn' },
{ pages: ['borrow'], label: 'Borrow' },
{ pages: ['portfolio'], label: 'Portfolio' },
...(ENABLE_HLS ? [{ pages: ['hls-farm', 'hls-staking'] as Page[], label: 'High Leverage' }] : []),
]
export default function DesktopHeader() {

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 512 512">
<path
fill="currentColor"
d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 120 120">
<path
fill="currentColor"
d="M0.3,3.8l46.3,61.9L0,116.2h10.5l40.8-44.1l33,44.1H120L71.1,50.7l43.4-46.9H104L66.4,44.5L36,3.8
H0.3z M15.7,11.6h16.4l72.4,96.9H88.2L15.7,11.6z"
/>
</svg>

After

Width:  |  Height:  |  Size: 289 B

View File

@ -7,6 +7,7 @@ export { default as ArrowCircledTopRight } from 'components/Icons/ArrowCircledTo
export { default as ArrowDownLine } from 'components/Icons/ArrowDownLine.svg'
export { default as ArrowRight } from 'components/Icons/ArrowRight.svg'
export { default as ArrowUpLine } from 'components/Icons/ArrowUpLine.svg'
export { default as Chain } from 'components/Icons/Chain.svg'
export { default as Check } from 'components/Icons/Check.svg'
export { default as CheckCircled } from 'components/Icons/CheckCircled.svg'
export { default as ChevronDown } from 'components/Icons/ChevronDown.svg'
@ -54,6 +55,7 @@ export { default as SwapIcon } from 'components/Icons/SwapIcon.svg'
export { default as ThreeDots } from 'components/Icons/ThreeDots.svg'
export { default as TooltipArrow } from 'components/Icons/TooltipArrow.svg'
export { default as TrashBin } from 'components/Icons/TrashBin.svg'
export { default as Twitter } from 'components/Icons/Twitter.svg'
export { default as VerticalThreeLine } from 'components/Icons/VerticalThreeLine.svg'
export { default as Wallet } from 'components/Icons/Wallet.svg'
// @endindex

View File

@ -1,5 +1,4 @@
import classNames from 'classnames'
import { useParams } from 'react-router-dom'
import { menuTree } from 'components/Header/DesktopHeader'
import { Logo } from 'components/Icons'
@ -9,13 +8,14 @@ import useStore from 'store'
import { getRoute } from 'utils/route'
export default function DesktopNavigation() {
const { address } = useParams()
const address = useStore((s) => s.address)
const accountId = useAccountId()
const focusComponent = useStore((s) => s.focusComponent)
function getIsActive(pages: string[]) {
return pages.some((page) => location.pathname.includes(page))
const segments = location.pathname.split('/')
return pages.some((page) => segments.includes(page))
}
return (
@ -25,7 +25,7 @@ export default function DesktopNavigation() {
)}
>
<NavLink href={getRoute('trade', address, accountId)}>
<span className='block h-10 w-10'>
<span className='block w-10 h-10'>
<Logo className='text-white' />
</span>
</NavLink>

View File

@ -1,6 +1,6 @@
import classNames from 'classnames'
import React, { ReactNode, useMemo } from 'react'
import { NavLink } from 'react-router-dom'
import { ReactNode, useMemo } from 'react'
import { NavLink, useParams } from 'react-router-dom'
import { FormattedNumber } from 'components/FormattedNumber'
import Loading from 'components/Loading'
@ -30,6 +30,7 @@ interface Props {
export default function PortfolioCard(props: Props) {
const { data: account } = useAccount(props.accountId)
const { health } = useHealthComputer(account)
const { address: urlAddress } = useParams()
const { data: prices } = usePrices()
const currentAccountId = useAccountId()
const { allAssets: lendingAssets } = useLendingMarketAssetsTableData()
@ -91,7 +92,7 @@ export default function PortfolioCard(props: Props) {
return (
<NavLink
to={getRoute(`portfolio/${props.accountId}` as Page, address, currentAccountId)}
to={getRoute(`portfolio/${props.accountId}` as Page, urlAddress, currentAccountId)}
className={classNames('w-full hover:bg-white/5', !reduceMotion && 'transition-all')}
>
<Skeleton

View File

@ -42,7 +42,7 @@ export default function AccountSummary() {
if (!walletAddress && !urlAddress) return <ConnectInfo />
if (!isLoading && accountIds?.length === 0) {
if (!isLoading && accountIds && accountIds.length === 0) {
return (
<Card
className='w-full h-fit bg-white/5'
@ -72,7 +72,7 @@ export default function AccountSummary() {
<div
className={classNames('grid w-full grid-cols-1 gap-6', 'md:grid-cols-2', 'lg:grid-cols-3')}
>
{accountIds.map((accountId: string, index: number) => {
{accountIds?.map((accountId: string, index: number) => {
return <PortfolioCard key={accountId} accountId={accountId} />
})}
</div>

View File

@ -4,17 +4,18 @@ import Intro from 'components/Intro'
import useStore from 'store'
export default function PortfolioIntro() {
const { address } = useParams()
const walletAddress = useStore((s) => s.address)
const { address: urlAddress } = useParams()
const address = useStore((s) => s.address)
const isCurrentWalllet = !urlAddress || urlAddress === address
return (
<Intro
text={
address && !walletAddress ? (
!isCurrentWalllet ? (
<>
This is the <span className='text-white'>Portfolio</span> of the address{' '}
<span className='text-white'>{address}</span>. You can see all Credit Accounts of this
address, but you can&apos;t interact with them.
<span className='text-white'>{urlAddress}</span>. You can see all Credit Accounts of
this address, but you can&apos;t interact with them.
</>
) : (
<>

View File

@ -3,6 +3,8 @@ import { Navigate, Outlet, Route, Routes as RoutesWrapper } from 'react-router-d
import Layout from 'pages/_layout'
import BorrowPage from 'pages/BorrowPage'
import FarmPage from 'pages/FarmPage'
import HLSFarmPage from 'pages/HLSFarmPage'
import HLSStakingPage from 'pages/HLSStakingPage'
import LendPage from 'pages/LendPage'
import MobilePage from 'pages/MobilePage'
import PortfolioAccountPage from 'pages/PortfolioAccountPage'
@ -25,6 +27,8 @@ export default function Routes() {
<Route path='/borrow' element={<BorrowPage />} />
<Route path='/portfolio' element={<PortfolioPage />} />
<Route path='/mobile' element={<MobilePage />} />
<Route path='/hls-staking' element={<HLSStakingPage />} />
<Route path='/hls-farm' element={<HLSFarmPage />} />
<Route path='/' element={<TradePage />} />
<Route path='/wallets/:address'>
<Route path='trade' element={<TradePage />} />
@ -35,6 +39,8 @@ export default function Routes() {
<Route path='portfolio/:accountId'>
<Route path='' element={<PortfolioAccountPage />} />
</Route>
<Route path='hls-staking' element={<HLSStakingPage />} />
<Route path='hls-farm' element={<HLSFarmPage />} />
<Route path='' element={<TradePage />} />
</Route>
<Route path='*' element={<Navigate to='/' />} />

View File

@ -0,0 +1,55 @@
import classNames from 'classnames'
import { useLocation, useParams } from 'react-router-dom'
import useClipboard from 'react-use-clipboard'
import Button from 'components/Button'
import { Chain, Check, Twitter } from 'components/Icons'
import Text from 'components/Text'
import { Tooltip } from 'components/Tooltip'
import ConditionalWrapper from 'hocs/ConditionalWrapper'
import { DocURL } from 'types/enums/docURL'
interface Props {
text: string
}
export default function ShareBar(props: Props) {
const { address } = useParams()
const { pathname } = useLocation()
const currentUrl = `https://${location.host}${pathname}`
const [isCopied, setCopied] = useClipboard(currentUrl, {
successDuration: 1000 * 5,
})
if (!window || !address) return null
return (
<div className='flex justify-end w-full gap-4'>
<ConditionalWrapper
condition={isCopied}
wrapper={(children) => (
<Tooltip type='info' content={<Text size='2xs'>Link copied!</Text>}>
{children}
</Tooltip>
)}
>
<Button
color='secondary'
iconClassName='w-4 h-4'
className={classNames('!p-2', isCopied && '!bg-transparent')}
leftIcon={isCopied ? <Check /> : <Chain />}
onClick={setCopied}
/>
</ConditionalWrapper>
<Button
color='secondary'
iconClassName='w-4 h-4'
className='!p-2'
leftIcon={<Twitter />}
onClick={(e) => {
e.preventDefault()
window.open(`${DocURL.X_SHARE_URL}?text=${props.text} ${currentUrl}`, '_blank')
}}
/>
</div>
)
}

View File

@ -224,7 +224,8 @@ export class OsmosisTheGraphDataFeed implements IDatafeedChartApi {
}
const filler = Array.from({ length: this.batchSize - bars.length }).map((_, index) => ({
time: (bars[0]?.time || new Date().getTime()) - index * this.minutesPerInterval[resolution],
time:
(bars[0]?.time || new Date().getTime()) - index * this.minutesPerInterval[resolution],
close: 0,
open: 0,
high: 0,

View File

@ -1,5 +1,5 @@
import { Suspense, useEffect, useMemo } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import AccountCreateFirst from 'components/Account/AccountCreateFirst'
import { CircularProgress } from 'components/CircularProgress'
@ -27,6 +27,7 @@ function FetchLoading() {
function Content() {
const address = useStore((s) => s.address)
const { address: urlAddress } = useParams()
const navigate = useNavigate()
const { pathname } = useLocation()
const { data: accountIds, isLoading: isLoadingAccounts } = useAccountIds(address || '')
@ -39,18 +40,26 @@ function Content() {
)
useEffect(() => {
const page = getPage(pathname)
if (page === 'portfolio' && urlAddress && urlAddress !== address) {
navigate(getRoute(page, urlAddress as string))
useStore.setState({ balances: walletBalances, focusComponent: null })
return
}
if (
accountIds &&
accountIds.length !== 0 &&
BN(baseBalance).isGreaterThanOrEqualTo(defaultFee.amount[0].amount)
) {
navigate(getRoute(getPage(pathname), address, accountIds[0]))
navigate(getRoute(page, address, accountIds[0]))
useStore.setState({ balances: walletBalances, focusComponent: null })
}
}, [accountIds, baseBalance, navigate, pathname, address, walletBalances])
}, [accountIds, baseBalance, navigate, pathname, address, walletBalances, urlAddress])
if (isLoadingAccounts || isLoadingBalances) return <FetchLoading />
if (BN(baseBalance).isLessThan(defaultFee.amount[0].amount)) return <WalletBridges />
if (accountIds.length === 0) return <AccountCreateFirst />
if (accountIds && accountIds.length === 0) return <AccountCreateFirst />
return null
}

9
src/constants/pages.ts Normal file
View File

@ -0,0 +1,9 @@
export const EARN_TABS: Tab[] = [
{ page: 'lend', name: 'Lend' },
{ page: 'farm', name: 'Farm' },
]
export const HLS_TABS: Tab[] = [
{ page: 'hls-farm', name: 'Farm' },
{ page: 'hls-staking', name: 'Staking' },
]

View File

@ -2,9 +2,9 @@ import useSWR from 'swr'
import getAccountIds from 'api/wallets/getAccountIds'
export default function useAccountIds(address?: string) {
export default function useAccountIds(address?: string, suspense = true) {
return useSWR(`wallets/${address}/account-ids`, () => getAccountIds(address), {
suspense: true,
suspense: suspense,
fallback: [] as string[],
revalidateOnFocus: false,
})

View File

@ -2,12 +2,13 @@ import FarmIntro from 'components/Earn/Farm/FarmIntro'
import { AvailableVaults, DepositedVaults } from 'components/Earn/Farm/Vaults'
import Tab from 'components/Earn/Tab'
import MigrationBanner from 'components/MigrationBanner'
import { EARN_TABS } from 'constants/pages'
export default function FarmPage() {
return (
<div className='flex flex-wrap w-full gap-6'>
<MigrationBanner />
<Tab isFarm />
<Tab tabs={EARN_TABS} activeTabIdx={1} />
<FarmIntro />
<DepositedVaults />
<AvailableVaults />

12
src/pages/HLSFarmPage.tsx Normal file
View File

@ -0,0 +1,12 @@
import Tab from 'components/Earn/Tab'
import MigrationBanner from 'components/MigrationBanner'
import { HLS_TABS } from 'constants/pages'
export default function HLSFarmPage() {
return (
<div className='flex flex-wrap w-full gap-6'>
<MigrationBanner />
<Tab tabs={HLS_TABS} activeTabIdx={0} />
</div>
)
}

View File

@ -0,0 +1,12 @@
import Tab from 'components/Earn/Tab'
import MigrationBanner from 'components/MigrationBanner'
import { HLS_TABS } from 'constants/pages'
export default function HLSStakingPage() {
return (
<div className='flex flex-wrap w-full gap-6'>
<MigrationBanner />
<Tab tabs={HLS_TABS} activeTabIdx={1} />
</div>
)
}

View File

@ -1,7 +1,8 @@
import LendIntro from 'components/Earn/Lend/LendIntro'
import LendingMarketsTable from 'components/Earn/Lend/LendingMarketsTable'
import LendIntro from 'components/Earn/Lend/LendIntro'
import Tab from 'components/Earn/Tab'
import MigrationBanner from 'components/MigrationBanner'
import { EARN_TABS } from 'constants/pages'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
export default function LendPage() {
@ -9,7 +10,7 @@ export default function LendPage() {
return (
<div className='flex flex-wrap w-full gap-6'>
<MigrationBanner />
<Tab />
<Tab tabs={EARN_TABS} activeTabIdx={0} />
<LendIntro />
<LendingMarketsTable data={accountLentAssets} title='Lent Assets' />
<LendingMarketsTable data={availableAssets} title='Available Markets' />

View File

@ -4,6 +4,7 @@ import MigrationBanner from 'components/MigrationBanner'
import Balances from 'components/Portfolio/Account/Balances'
import BreadCrumbs from 'components/Portfolio/Account/BreadCrumbs'
import Summary from 'components/Portfolio/Account/Summary'
import ShareBar from 'components/ShareBar'
import useAccountId from 'hooks/useAccountId'
import { getRoute } from 'utils/route'
@ -23,6 +24,7 @@ export default function PortfolioAccountPage() {
<BreadCrumbs accountId={accountId} />
<Summary accountId={accountId} />
<Balances accountId={accountId} />
<ShareBar text={`Have a look at Credit Account ${accountId} on @mars_protocol!`} />
</div>
)
}

View File

@ -2,6 +2,7 @@ import MigrationBanner from 'components/MigrationBanner'
import AccountOverview from 'components/Portfolio/Overview'
import PortfolioSummary from 'components/Portfolio/Overview/Summary'
import PortfolioIntro from 'components/Portfolio/PortfolioIntro'
import ShareBar from 'components/ShareBar'
export default function PortfolioPage() {
return (
@ -10,6 +11,7 @@ export default function PortfolioPage() {
<PortfolioIntro />
<PortfolioSummary />
<AccountOverview />
<ShareBar text='Have a look at this @mars_protocol portfolio!' />
</div>
)
}

View File

@ -3,6 +3,7 @@ export enum DocURL {
BORROW_LENDING_URL = 'https://docs.marsprotocol.io/docs/learn/mars-v2/borrow',
COOKIE_POLICY_URL = 'https://docs.marsprotocol.io/docs/overview/legal/cookie-policy',
DOCS_URL = 'https://docs.marsprotocol.io/',
FARM_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/tutorials/farming/farming-intro',
MANAGE_ACCOUNT_URL = 'https://docs.marsprotocol.io/docs/learn/tutorials/credit-accounts/credit-accounts-intro',
ROVER_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/mars-v2/credit-accounts',
PRIVACY_POLICY_URL = 'https://docs.marsprotocol.io/docs/overview/legal/privacy-policy',
@ -10,4 +11,5 @@ export enum DocURL {
TRADING_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/tutorials/trading/trading-intro',
V1_URL = 'https://v1.marsprotocol.io',
WALLET_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/tutorials/basics/connecting-your-wallet',
X_SHARE_URL = 'https://x.com/intent/tweet',
}

View File

@ -0,0 +1,4 @@
interface Tab {
page: Page
name: string
}

View File

@ -1 +1,9 @@
type Page = 'trade' | 'borrow' | 'farm' | 'lend' | 'portfolio' | 'portfolio/{accountId}'
type Page =
| 'trade'
| 'borrow'
| 'farm'
| 'lend'
| 'portfolio'
| 'portfolio/{accountId}'
| 'hls-farm'
| 'hls-staking'

View File

@ -22,3 +22,5 @@ export const DEFAULT_PORTFOLIO_STATS = [
{ title: null, sub: 'APR' },
{ title: null, sub: 'Account Leverage' },
]
export const ENABLE_HLS = false