give account views a url

This commit is contained in:
saml33 2023-07-11 23:14:44 +10:00
parent a35d8e3610
commit d5d58626fc
7 changed files with 145 additions and 135 deletions

View File

@ -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)}

View File

@ -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>

View File

@ -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:

View File

@ -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)
}

View File

@ -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
}

View File

@ -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`}
/>

View File

@ -26,8 +26,6 @@ export default function useAccountHourlyVolumeStats() {
return {
hourlyVolumeData,
loadingHourlyVolumeData,
fetchingHourlyVolumeData,
loadingHourlyVolume,
}
}