give account views a url
This commit is contained in:
parent
a35d8e3610
commit
d5d58626fc
|
@ -15,7 +15,7 @@ const CHART_TABS: ViewToShow[] = [
|
|||
|
||||
const AccountChart = ({
|
||||
chartName,
|
||||
setViewToShow,
|
||||
handleViewChange,
|
||||
customTooltip,
|
||||
data,
|
||||
hideChart,
|
||||
|
@ -24,7 +24,7 @@ const AccountChart = ({
|
|||
yKey,
|
||||
}: {
|
||||
chartName: ViewToShow
|
||||
setViewToShow: (chart: ViewToShow) => void
|
||||
handleViewChange: (view: ViewToShow) => void
|
||||
customTooltip?: ContentType<number, string>
|
||||
data: PerformanceDataItem[] | HourlyFundingChartData[] | undefined
|
||||
hideChart: () => void
|
||||
|
@ -65,7 +65,7 @@ const AccountChart = ({
|
|||
? 'bg-th-bkg-3 text-th-active md:hover:text-th-active'
|
||||
: 'text-th-fgd-3 md:hover:text-th-fgd-2'
|
||||
}`}
|
||||
onClick={() => setViewToShow(tab)}
|
||||
onClick={() => handleViewChange(tab)}
|
||||
key={tab}
|
||||
>
|
||||
{t(tab)}
|
||||
|
|
|
@ -25,13 +25,13 @@ const AccountHeroStats = ({
|
|||
accountValue,
|
||||
rollingDailyData,
|
||||
setShowPnlHistory,
|
||||
setViewToShow,
|
||||
handleViewChange,
|
||||
}: {
|
||||
accountPnl: number
|
||||
accountValue: number
|
||||
rollingDailyData: PerformanceDataItem[]
|
||||
setShowPnlHistory: (show: boolean) => void
|
||||
setViewToShow: (view: ViewToShow) => void
|
||||
handleViewChange: (view: ViewToShow) => void
|
||||
}) => {
|
||||
const { t } = useTranslation(['common', 'account'])
|
||||
const { group } = useMangoGroup()
|
||||
|
@ -162,10 +162,6 @@ const AccountHeroStats = ({
|
|||
return volume
|
||||
}, [hourlyVolumeData])
|
||||
|
||||
const handleViewToShow = (viewName: ViewToShow) => {
|
||||
setViewToShow(viewName)
|
||||
}
|
||||
|
||||
const loadingTotalVolume = fetchingVolumeTotalData || loadingVolumeTotalData
|
||||
|
||||
return (
|
||||
|
@ -222,19 +218,21 @@ const AccountHeroStats = ({
|
|||
{t('health')}
|
||||
</p>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
className="hidden md:block"
|
||||
content={t('account:health-contributions')}
|
||||
delay={100}
|
||||
>
|
||||
<IconButton
|
||||
className="text-th-fgd-3"
|
||||
hideBg
|
||||
onClick={() => handleViewToShow('health-contributions')}
|
||||
{mangoAccountAddress ? (
|
||||
<Tooltip
|
||||
className="hidden md:block"
|
||||
content={t('account:health-contributions')}
|
||||
delay={100}
|
||||
>
|
||||
<ChartBarIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<IconButton
|
||||
className="text-th-fgd-3"
|
||||
hideBg
|
||||
onClick={() => handleViewChange('health-contributions')}
|
||||
>
|
||||
<ChartBarIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mt-1 mb-0.5 flex items-center space-x-3">
|
||||
<p className="text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
|
||||
|
@ -332,7 +330,7 @@ const AccountHeroStats = ({
|
|||
<IconButton
|
||||
className="text-th-fgd-3"
|
||||
hideBg
|
||||
onClick={() => handleViewToShow('pnl')}
|
||||
onClick={() => handleViewChange('pnl')}
|
||||
>
|
||||
<ChartBarIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
|
@ -381,7 +379,7 @@ const AccountHeroStats = ({
|
|||
<IconButton
|
||||
className="text-th-fgd-3"
|
||||
hideBg
|
||||
onClick={() => handleViewToShow('hourly-volume')}
|
||||
onClick={() => handleViewChange('hourly-volume')}
|
||||
>
|
||||
<ChartBarIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
|
@ -438,7 +436,7 @@ const AccountHeroStats = ({
|
|||
className="text-th-fgd-3"
|
||||
hideBg
|
||||
onClick={() =>
|
||||
handleViewToShow('cumulative-interest-value')
|
||||
handleViewChange('cumulative-interest-value')
|
||||
}
|
||||
>
|
||||
<ChartBarIcon className="h-5 w-5" />
|
||||
|
@ -480,7 +478,7 @@ const AccountHeroStats = ({
|
|||
<IconButton
|
||||
className="text-th-fgd-3"
|
||||
hideBg
|
||||
onClick={() => handleViewToShow('hourly-funding')}
|
||||
onClick={() => handleViewChange('hourly-funding')}
|
||||
>
|
||||
<ChartBarIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import AccountActions from './AccountActions'
|
||||
import AccountTabs from './AccountTabs'
|
||||
import AccountChart from './AccountChart'
|
||||
|
@ -17,9 +17,9 @@ import VolumeChart from './VolumeChart'
|
|||
import AccountHeroStats from './AccountHeroStats'
|
||||
import AccountValue from './AccountValue'
|
||||
import useAccountPerformanceData from 'hooks/useAccountPerformanceData'
|
||||
import useAccountHourlyVolumeStats from 'hooks/useAccountHourlyVolumeStats'
|
||||
import HealthContributions from './HealthContributions'
|
||||
import { PerformanceDataItem } from 'types'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
const TABS = ['account-value', 'account:assets-liabilities']
|
||||
|
||||
|
@ -36,7 +36,6 @@ const AccountPage = () => {
|
|||
const { t } = useTranslation(['common', 'account'])
|
||||
const { group } = useMangoGroup()
|
||||
const { mangoAccount } = useMangoAccount()
|
||||
const [viewToShow, setViewToShow] = useState<ViewToShow>('')
|
||||
const [showPnlHistory, setShowPnlHistory] = useState<boolean>(false)
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.md : false
|
||||
|
@ -45,6 +44,16 @@ const AccountPage = () => {
|
|||
'account-value'
|
||||
)
|
||||
const { performanceData, rollingDailyData } = useAccountPerformanceData()
|
||||
const router = useRouter()
|
||||
const { view } = router.query
|
||||
|
||||
const handleViewChange = useCallback(
|
||||
(view: ViewToShow) => {
|
||||
const query = { ...router.query, ['view']: view }
|
||||
router.push({ pathname: router.pathname, query })
|
||||
},
|
||||
[router]
|
||||
)
|
||||
|
||||
const handleCloseDailyPnlModal = () => {
|
||||
setShowPnlHistory(false)
|
||||
|
@ -88,7 +97,7 @@ const AccountPage = () => {
|
|||
]
|
||||
}, [accountPnl, accountValue, performanceData])
|
||||
|
||||
return !viewToShow ? (
|
||||
return !view ? (
|
||||
<>
|
||||
<div className="flex flex-col border-b-0 border-th-bkg-3 px-6 py-4 lg:flex-row lg:items-center lg:justify-between lg:border-b">
|
||||
<div>
|
||||
|
@ -113,7 +122,7 @@ const AccountPage = () => {
|
|||
accountValue={accountValue}
|
||||
latestAccountData={latestAccountData}
|
||||
rollingDailyData={rollingDailyData}
|
||||
setViewToShow={setViewToShow}
|
||||
handleViewChange={handleViewChange}
|
||||
/>
|
||||
) : null}
|
||||
{activeTab === 'account:assets-liabilities' ? (
|
||||
|
@ -129,8 +138,8 @@ const AccountPage = () => {
|
|||
accountPnl={accountPnl}
|
||||
accountValue={accountValue}
|
||||
rollingDailyData={rollingDailyData}
|
||||
setViewToShow={setViewToShow}
|
||||
setShowPnlHistory={setShowPnlHistory}
|
||||
handleViewChange={handleViewChange}
|
||||
/>
|
||||
<AccountTabs />
|
||||
{showPnlHistory ? (
|
||||
|
@ -143,9 +152,9 @@ const AccountPage = () => {
|
|||
</>
|
||||
) : (
|
||||
<AccountView
|
||||
view={viewToShow}
|
||||
setViewToShow={setViewToShow}
|
||||
view={view as ViewToShow}
|
||||
latestAccountData={latestAccountData}
|
||||
handleViewChange={handleViewChange}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -154,27 +163,31 @@ export default AccountPage
|
|||
|
||||
const AccountView = ({
|
||||
view,
|
||||
setViewToShow,
|
||||
handleViewChange,
|
||||
latestAccountData,
|
||||
}: {
|
||||
view: ViewToShow
|
||||
setViewToShow: (v: ViewToShow) => void
|
||||
latestAccountData: PerformanceDataItem[]
|
||||
handleViewChange: (view: ViewToShow) => void
|
||||
}) => {
|
||||
const { hourlyVolumeData, loadingHourlyVolume } =
|
||||
useAccountHourlyVolumeStats()
|
||||
const router = useRouter()
|
||||
const { address } = router.query
|
||||
const { performanceData } = useAccountPerformanceData()
|
||||
|
||||
const handleHideChart = () => {
|
||||
setViewToShow('')
|
||||
}
|
||||
const handleHideChart = useCallback(() => {
|
||||
if (address) {
|
||||
router.push(`/?address=${address}`)
|
||||
} else {
|
||||
router.push('/')
|
||||
}
|
||||
}, [router])
|
||||
|
||||
switch (view) {
|
||||
case 'account-value':
|
||||
return (
|
||||
<AccountChart
|
||||
chartName="account-value"
|
||||
setViewToShow={setViewToShow}
|
||||
handleViewChange={handleViewChange}
|
||||
data={performanceData?.concat(latestAccountData)}
|
||||
hideChart={handleHideChart}
|
||||
yKey="account_equity"
|
||||
|
@ -184,7 +197,7 @@ const AccountView = ({
|
|||
return (
|
||||
<AccountChart
|
||||
chartName="pnl"
|
||||
setViewToShow={setViewToShow}
|
||||
handleViewChange={handleViewChange}
|
||||
data={performanceData?.concat(latestAccountData)}
|
||||
hideChart={handleHideChart}
|
||||
yKey="pnl"
|
||||
|
@ -194,7 +207,7 @@ const AccountView = ({
|
|||
return (
|
||||
<AccountChart
|
||||
chartName="cumulative-interest-value"
|
||||
setViewToShow={setViewToShow}
|
||||
handleViewChange={handleViewChange}
|
||||
data={performanceData?.concat(latestAccountData)}
|
||||
hideChart={handleHideChart}
|
||||
yKey="interest_value"
|
||||
|
@ -203,13 +216,7 @@ const AccountView = ({
|
|||
case 'hourly-funding':
|
||||
return <FundingChart hideChart={handleHideChart} />
|
||||
case 'hourly-volume':
|
||||
return (
|
||||
<VolumeChart
|
||||
chartData={hourlyVolumeData}
|
||||
hideChart={handleHideChart}
|
||||
loading={loadingHourlyVolume}
|
||||
/>
|
||||
)
|
||||
return <VolumeChart hideChart={handleHideChart} />
|
||||
case 'health-contributions':
|
||||
return <HealthContributions hideView={handleHideChart} />
|
||||
default:
|
||||
|
|
|
@ -26,12 +26,12 @@ const AccountValue = ({
|
|||
accountValue,
|
||||
latestAccountData,
|
||||
rollingDailyData,
|
||||
setViewToShow,
|
||||
handleViewChange,
|
||||
}: {
|
||||
accountValue: number
|
||||
latestAccountData: PerformanceDataItem[]
|
||||
rollingDailyData: PerformanceDataItem[]
|
||||
setViewToShow: (chart: ViewToShow) => void
|
||||
handleViewChange: (view: ViewToShow) => void
|
||||
}) => {
|
||||
const { t } = useTranslation('common')
|
||||
const { theme } = useTheme()
|
||||
|
@ -62,7 +62,7 @@ const AccountValue = ({
|
|||
}
|
||||
|
||||
const handleShowAccountValueChart = () => {
|
||||
setViewToShow('account-value')
|
||||
handleViewChange('account-value')
|
||||
setShowExpandChart(false)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { useMemo, useState } from 'react'
|
|||
import { HealthType } from '@blockworks-foundation/mango-v4'
|
||||
import {
|
||||
ArrowLeftIcon,
|
||||
NoSymbolIcon,
|
||||
QuestionMarkCircleIcon,
|
||||
} from '@heroicons/react/20/solid'
|
||||
import Tooltip from '@components/shared/Tooltip'
|
||||
|
@ -24,7 +25,7 @@ export interface HealthContribution {
|
|||
const HealthContributions = ({ hideView }: { hideView: () => void }) => {
|
||||
const { t } = useTranslation(['common', 'account', 'trade'])
|
||||
const { group } = useMangoGroup()
|
||||
const { mangoAccount } = useMangoAccount()
|
||||
const { mangoAccount, mangoAccountAddress } = useMangoAccount()
|
||||
const [initActiveIndex, setInitActiveIndex] = useState<number | undefined>(
|
||||
undefined
|
||||
)
|
||||
|
@ -164,7 +165,7 @@ const HealthContributions = ({ hideView }: { hideView: () => void }) => {
|
|||
})
|
||||
}, [maintHealthContributions])
|
||||
|
||||
return group && mangoAccount ? (
|
||||
return group ? (
|
||||
<>
|
||||
<div className="hide-scroll flex h-14 items-center space-x-4 overflow-x-auto border-b border-th-bkg-3">
|
||||
<button
|
||||
|
@ -175,74 +176,83 @@ const HealthContributions = ({ hideView }: { hideView: () => void }) => {
|
|||
</button>
|
||||
<h2 className="text-lg">{t('account:health-contributions')}</h2>
|
||||
</div>
|
||||
<div className="mx-auto grid max-w-[1140px] grid-cols-2 gap-6 p-6 sm:gap-8">
|
||||
<div className="col-span-1 flex h-full flex-col items-center">
|
||||
<Tooltip content={t('account:tooltip-init-health')}>
|
||||
<h3 className="tooltip-underline text-xs sm:text-base">
|
||||
{t('account:init-health-contributions')}
|
||||
</h3>
|
||||
</Tooltip>
|
||||
<HealthContributionsChart
|
||||
data={initChartData}
|
||||
activeIndex={initActiveIndex}
|
||||
setActiveIndex={setInitActiveIndex}
|
||||
/>
|
||||
{mangoAccountAddress ? (
|
||||
<>
|
||||
<div className="mx-auto grid max-w-[1140px] grid-cols-2 gap-6 p-6 sm:gap-8">
|
||||
<div className="col-span-1 flex h-full flex-col items-center">
|
||||
<Tooltip content={t('account:tooltip-init-health')}>
|
||||
<h3 className="tooltip-underline text-xs sm:text-base">
|
||||
{t('account:init-health-contributions')}
|
||||
</h3>
|
||||
</Tooltip>
|
||||
<HealthContributionsChart
|
||||
data={initChartData}
|
||||
activeIndex={initActiveIndex}
|
||||
setActiveIndex={setInitActiveIndex}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col items-center">
|
||||
<Tooltip content={t('account:tooltip-maint-health')}>
|
||||
<h3 className="tooltip-underline text-xs sm:text-base">
|
||||
{t('account:maint-health-contributions')}
|
||||
</h3>
|
||||
</Tooltip>
|
||||
<HealthContributionsChart
|
||||
data={maintChartData}
|
||||
activeIndex={maintActiveIndex}
|
||||
setActiveIndex={setMaintActiveIndex}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 mx-auto flex max-w-[600px] flex-wrap justify-center space-x-4">
|
||||
{[...maintChartData]
|
||||
.sort((a, b) => b.contribution - a.contribution)
|
||||
.map((d, i) => {
|
||||
return (
|
||||
<div
|
||||
key={d.asset + i}
|
||||
className={`default-transition flex h-7 cursor-pointer items-center md:hover:text-th-active`}
|
||||
onClick={() => handleLegendClick(d)}
|
||||
onMouseEnter={() => handleLegendMouseEnter(d)}
|
||||
onMouseLeave={handleLegendMouseLeave}
|
||||
>
|
||||
{renderLegendLogo(d.asset)}
|
||||
<span className={`default-transition`}>{d.asset}</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{maintHealthTokens.length ? (
|
||||
<div className="border-t border-th-bkg-3 pt-6">
|
||||
<h2 className="mb-1 px-6 text-lg">{t('tokens')}</h2>
|
||||
<TokensHealthTable
|
||||
initTokens={initHealthTokens}
|
||||
maintTokens={maintHealthTokens}
|
||||
handleLegendClick={handleLegendClick}
|
||||
handleLegendMouseEnter={handleLegendMouseEnter}
|
||||
handleLegendMouseLeave={handleLegendMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{maintHealthMarkets.length ? (
|
||||
<div className="pt-6">
|
||||
<h2 className="mb-1 px-6 text-lg">{t('markets')}</h2>
|
||||
<MarketsHealthTable
|
||||
initMarkets={initHealthMarkets}
|
||||
maintMarkets={maintHealthMarkets}
|
||||
handleLegendClick={handleLegendClick}
|
||||
handleLegendMouseEnter={handleLegendMouseEnter}
|
||||
handleLegendMouseLeave={handleLegendMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<div className="mx-6 mt-6 flex flex-col items-center rounded-lg border border-th-bkg-3 p-8">
|
||||
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
|
||||
<p>{t('account:no-data')}</p>
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col items-center">
|
||||
<Tooltip content={t('account:tooltip-maint-health')}>
|
||||
<h3 className="tooltip-underline text-xs sm:text-base">
|
||||
{t('account:maint-health-contributions')}
|
||||
</h3>
|
||||
</Tooltip>
|
||||
<HealthContributionsChart
|
||||
data={maintChartData}
|
||||
activeIndex={maintActiveIndex}
|
||||
setActiveIndex={setMaintActiveIndex}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 mx-auto flex max-w-[600px] flex-wrap justify-center space-x-4">
|
||||
{[...maintChartData]
|
||||
.sort((a, b) => b.contribution - a.contribution)
|
||||
.map((d, i) => {
|
||||
return (
|
||||
<div
|
||||
key={d.asset + i}
|
||||
className={`default-transition flex h-7 cursor-pointer items-center md:hover:text-th-active`}
|
||||
onClick={() => handleLegendClick(d)}
|
||||
onMouseEnter={() => handleLegendMouseEnter(d)}
|
||||
onMouseLeave={handleLegendMouseLeave}
|
||||
>
|
||||
{renderLegendLogo(d.asset)}
|
||||
<span className={`default-transition`}>{d.asset}</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{maintHealthTokens.length ? (
|
||||
<div className="border-t border-th-bkg-3 pt-6">
|
||||
<h2 className="mb-1 px-6 text-lg">{t('tokens')}</h2>
|
||||
<TokensHealthTable
|
||||
initTokens={initHealthTokens}
|
||||
maintTokens={maintHealthTokens}
|
||||
handleLegendClick={handleLegendClick}
|
||||
handleLegendMouseEnter={handleLegendMouseEnter}
|
||||
handleLegendMouseLeave={handleLegendMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{maintHealthMarkets.length ? (
|
||||
<div className="pt-6">
|
||||
<h2 className="mb-1 px-6 text-lg">{t('markets')}</h2>
|
||||
<MarketsHealthTable
|
||||
initMarkets={initHealthMarkets}
|
||||
maintMarkets={maintHealthMarkets}
|
||||
handleLegendClick={handleLegendClick}
|
||||
handleLegendMouseEnter={handleLegendMouseEnter}
|
||||
handleLegendMouseLeave={handleLegendMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
)}
|
||||
</>
|
||||
) : null
|
||||
}
|
||||
|
|
|
@ -24,17 +24,14 @@ import { ArrowLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
|
|||
import { FadeInFadeOut } from '@components/shared/Transitions'
|
||||
import ContentBox from '@components/shared/ContentBox'
|
||||
import SheenLoader from '@components/shared/SheenLoader'
|
||||
import useAccountHourlyVolumeStats from 'hooks/useAccountHourlyVolumeStats'
|
||||
import useMangoAccount from 'hooks/useMangoAccount'
|
||||
|
||||
const VolumeChart = ({
|
||||
chartData,
|
||||
hideChart,
|
||||
loading,
|
||||
}: {
|
||||
chartData: FormattedHourlyAccountVolumeData[] | undefined
|
||||
hideChart: () => void
|
||||
loading: boolean
|
||||
}) => {
|
||||
const VolumeChart = ({ hideChart }: { hideChart: () => void }) => {
|
||||
const { t } = useTranslation(['account', 'common', 'stats'])
|
||||
const { mangoAccountAddress } = useMangoAccount()
|
||||
const { hourlyVolumeData: chartData, loadingHourlyVolume: loading } =
|
||||
useAccountHourlyVolumeStats()
|
||||
const [daysToShow, setDaysToShow] = useState('30')
|
||||
const { theme } = useTheme()
|
||||
|
||||
|
@ -159,8 +156,8 @@ const VolumeChart = ({
|
|||
onChange={(v) => setDaysToShow(v)}
|
||||
/>
|
||||
</div>
|
||||
{loading ? (
|
||||
<SheenLoader className="flex flex-1">
|
||||
{loading && mangoAccountAddress ? (
|
||||
<SheenLoader className="mt-6 flex flex-1">
|
||||
<div
|
||||
className={`h-[calc(100vh-166px)] w-full rounded-lg bg-th-bkg-2`}
|
||||
/>
|
||||
|
|
|
@ -26,8 +26,6 @@ export default function useAccountHourlyVolumeStats() {
|
|||
|
||||
return {
|
||||
hourlyVolumeData,
|
||||
loadingHourlyVolumeData,
|
||||
fetchingHourlyVolumeData,
|
||||
loadingHourlyVolume,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue