diff --git a/components/account/AccountActions.tsx b/components/account/AccountActions.tsx index f9eabd0c..f3c95772 100644 --- a/components/account/AccountActions.tsx +++ b/components/account/AccountActions.tsx @@ -52,7 +52,7 @@ const AccountActions = () => { return ( <> {isUnownedAccount ? null : ( -
+
)} -
- -
+
diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index 729096ad..1be76b54 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -19,7 +19,9 @@ export type ViewToShow = export const handleViewChange = (view: ViewToShow, router: NextRouter) => { const query = { ...router.query, ['view']: view } - router.push({ pathname: router.pathname, query }) + router.push({ pathname: router.pathname, query }, undefined, { + shallow: true, + }) } const AccountPage = () => { diff --git a/components/account/AccountStats.tsx b/components/account/AccountStats.tsx index 701c2ad6..f5d3b000 100644 --- a/components/account/AccountStats.tsx +++ b/components/account/AccountStats.tsx @@ -6,14 +6,55 @@ import { useTranslation } from 'react-i18next' import { formatYAxis } from 'utils/formatting' import FundingChart from './FundingChart' import VolumeChart from './VolumeChart' +import { useQuery } from '@tanstack/react-query' +import useMangoAccount from 'hooks/useMangoAccount' +import { fetchFundingTotals, fetchVolumeTotals } from 'utils/account' +import Tooltip from '@components/shared/Tooltip' +import SheenLoader from '@components/shared/SheenLoader' +import FormatNumericValue from '@components/shared/FormatNumericValue' const AccountStats = ({ hideView }: { hideView: () => void }) => { const { t } = useTranslation(['common', 'account']) + const { mangoAccountAddress } = useMangoAccount() const { performanceData, loadingPerformanceData } = useAccountPerformanceData() const [pnlDaysToShow, setPnlDaysToShow] = useState('1') const [interestDaysToShow, setInterestDaysToShow] = useState('1') + const { data: fundingData, isLoading: loadingFunding } = useQuery( + ['funding', mangoAccountAddress], + () => fetchFundingTotals(mangoAccountAddress), + { + cacheTime: 1000 * 60 * 10, + staleTime: 1000 * 60, + retry: 3, + refetchOnWindowFocus: false, + enabled: !!mangoAccountAddress, + }, + ) + + const { data: volumeTotalData, isLoading: loadingVolumeTotalData } = useQuery( + ['total-volume', mangoAccountAddress], + () => fetchVolumeTotals(mangoAccountAddress), + { + cacheTime: 1000 * 60 * 10, + staleTime: 1000 * 60, + retry: 3, + refetchOnWindowFocus: false, + enabled: !!mangoAccountAddress, + }, + ) + + const fundingTotalValue = useMemo(() => { + if (fundingData?.length && mangoAccountAddress) { + return fundingData.reduce( + (a, c) => a + c.long_funding + c.short_funding, + 0, + ) + } + return 0.0 + }, [fundingData, mangoAccountAddress]) + const chartData = useMemo(() => { if (!performanceData || !performanceData.length) return [] const chartData = [] @@ -51,6 +92,7 @@ const AccountStats = ({ hideView }: { hideView: () => void }) => { title={t('pnl')} xKey="time" yKey="pnl" + small />
@@ -66,13 +108,57 @@ const AccountStats = ({ hideView }: { hideView: () => void }) => { title={t('cumulative-interest-value')} xKey="time" yKey="interest_value" + small />
-
- +
+
+ +

+ {t('account:total-funding-earned')} +

+
+ {loadingFunding && mangoAccountAddress ? ( + +
+ + ) : ( +

+ +

+ )} +
+
+ +
-
- +
+
+

+ {t('account:lifetime-volume')} +

+ {loadingVolumeTotalData && mangoAccountAddress ? ( + +
+ + ) : ( +

+ +

+ )} +
+
+ +
diff --git a/components/account/AccountValueChart.tsx b/components/account/AccountValueChart.tsx deleted file mode 100644 index 7ea76e45..00000000 --- a/components/account/AccountValueChart.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import SimpleAreaChart from '@components/shared/SimpleAreaChart' -import { COLORS } from '../../styles/colors' -import { IconButton } from '../shared/Button' -import { ArrowsPointingOutIcon } from '@heroicons/react/20/solid' -import { Transition } from '@headlessui/react' -import SheenLoader from '../shared/SheenLoader' -import useMangoAccount from 'hooks/useMangoAccount' -import { PerformanceDataItem } from 'types' -import { useCallback, useMemo, useState } from 'react' -import { useViewport } from 'hooks/useViewport' -import { handleViewChange } from './AccountPage' -import useAccountPerformanceData from 'hooks/useAccountPerformanceData' -import useThemeWrapper from 'hooks/useThemeWrapper' -import { useRouter } from 'next/router' - -const AccountValueChart = ({ - accountValue, - latestAccountData, - rollingDailyData, -}: { - accountValue: number - latestAccountData: PerformanceDataItem[] - rollingDailyData: PerformanceDataItem[] -}) => { - const { theme } = useThemeWrapper() - const router = useRouter() - const { mangoAccountAddress } = useMangoAccount() - const [showExpandChart, setShowExpandChart] = useState(false) - const { isTablet } = useViewport() - const { performanceLoading: loading } = useAccountPerformanceData() - - const accountValueChange = useMemo(() => { - if (!accountValue || !rollingDailyData.length) return 0 - const accountValueChange = accountValue - rollingDailyData[0].account_equity - return accountValueChange - }, [accountValue, rollingDailyData]) - - const onHoverMenu = (open: boolean, action: string) => { - if ( - (!open && action === 'onMouseEnter') || - (open && action === 'onMouseLeave') - ) { - setShowExpandChart(!open) - } - } - - const handleShowAccountValueChart = useCallback(() => { - handleViewChange('account-value', router) - setShowExpandChart(false) - }, [router]) - - return !loading ? ( - rollingDailyData.length ? ( -
onHoverMenu(showExpandChart, 'onMouseEnter')} - onMouseLeave={() => onHoverMenu(showExpandChart, 'onMouseLeave')} - > - = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] - } - data={rollingDailyData.concat(latestAccountData)} - name="accountValue" - xKey="time" - yKey="account_equity" - /> - - handleShowAccountValueChart()} - > - - - -
- ) : null - ) : mangoAccountAddress ? ( - -
- - ) : null -} - -export default AccountValueChart diff --git a/components/account/FundingChart.tsx b/components/account/FundingChart.tsx index 2d5c769a..1e6f001a 100644 --- a/components/account/FundingChart.tsx +++ b/components/account/FundingChart.tsx @@ -31,6 +31,7 @@ import { FadeInFadeOut } from '@components/shared/Transitions' import ContentBox from '@components/shared/ContentBox' import SheenLoader from '@components/shared/SheenLoader' import useThemeWrapper from 'hooks/useThemeWrapper' +import FormatNumericValue from '@components/shared/FormatNumericValue' type TempDataType = { [time: string]: { @@ -79,7 +80,7 @@ const FundingChart = () => { isFetching: fetchingFunding, refetch, } = useQuery( - ['hourly-funding'], + ['hourly-funding', mangoAccountAddress], () => fetchHourlyFunding(mangoAccountAddress), { cacheTime: 1000 * 60 * 10, @@ -167,12 +168,6 @@ const FundingChart = () => { const scaleDataTime = (data: HourlyFundingChartData[]) => { const scaledData = data.reduce((a: HourlyFundingChartData[], c) => { const found = a.find((item) => { - // const threshold = daysToShow === '7' ? 14400000 : 86400000 - // const currentDataTime = new Date(c.time).getTime() - // const date = new Date(item.time) - // const maxTime = date.getTime() + threshold - // return currentDataTime <= maxTime - const currentDataDate = new Date(c.time) const itemDate = new Date(item.time) return ( @@ -216,123 +211,141 @@ const FundingChart = () => { return filtered }, [chartData, daysToShow]) + const totalForTimePeriod = useMemo(() => { + if (!filteredData.length) return 0 + return filteredData.reduce((a, c) => a + c.total, 0) + }, [filteredData]) + return ( - -
-
-

{t('funding')}

-
- setDaysToShow(v)} - /> -
+ {loadingFunding || fetchingFunding ? ( - -
+ +
- ) : filteredData.find((d) => Math.abs(d.total) > 0) ? ( -
- - - } - /> - - - - - - - - - - - - {filteredData.map((entry, index) => { - return ( - 0 - ? 'url(#greenGradientBar)' - : 'url(#redGradientBar)' - } - /> - ) - })} - - formatDateAxis(v, parseInt(daysToShow))} - /> - formatYAxis(v)} - type="number" - /> - - - -
) : ( -
- -

{t('account:no-data')}

-
+ <> +
+
+

+ {t('funding')} +

+ {totalForTimePeriod ? ( + + + + ) : null} +
+ setDaysToShow(v)} + /> +
+ {filteredData.find((d) => Math.abs(d.total) > 0) ? ( +
+ + + } + /> + + + + + + + + + + + + {filteredData.map((entry, index) => { + return ( + 0 + ? 'url(#greenGradientBar)' + : 'url(#redGradientBar)' + } + /> + ) + })} + + + formatDateAxis(v, parseInt(daysToShow)) + } + /> + formatYAxis(v)} + type="number" + /> + + + +
+ ) : ( +
+ +

{t('account:no-data')}

+
+ )} + )} diff --git a/components/account/VolumeChart.tsx b/components/account/VolumeChart.tsx index f51ce654..d73ef134 100644 --- a/components/account/VolumeChart.tsx +++ b/components/account/VolumeChart.tsx @@ -26,6 +26,7 @@ import useAccountHourlyVolumeStats from 'hooks/useAccountHourlyVolumeStats' import useMangoAccount from 'hooks/useMangoAccount' import { DAILY_MILLISECONDS } from 'utils/constants' import useThemeWrapper from 'hooks/useThemeWrapper' +import FormatNumericValue from '@components/shared/FormatNumericValue' const VolumeChart = () => { const { t } = useTranslation(['account', 'common', 'stats']) @@ -141,101 +142,119 @@ const VolumeChart = () => { return filtered }, [chartData, daysToShow]) + const totalForTimePeriod = useMemo(() => { + if (!filteredData.length) return 0 + return filteredData.reduce((a, c) => a + c.total_volume_usd, 0) + }, [filteredData]) + return ( - -
-
-

{t('stats:volume')}

-
- setDaysToShow(v)} - /> -
+ {loading && mangoAccountAddress ? ( - -
+ +
- ) : filteredData.find((d) => d.total_volume_usd > 0) ? ( -
- - - } - /> - - - - - - - - {filteredData.map((entry, index) => { - return ( - - ) - })} - - formatDateAxis(v, parseInt(daysToShow))} - /> - formatYAxis(v)} - type="number" - /> - - - -
) : ( -
- -

{t('account:no-data')}

-
+ <> +
+
+

+ {t('stats:volume')} +

+ {totalForTimePeriod ? ( + + + + ) : null} +
+ setDaysToShow(v)} + /> +
+ {filteredData.find((d) => d.total_volume_usd > 0) ? ( +
+ + + } + /> + + + + + + + + {filteredData.map((entry, index) => { + return ( + + ) + })} + + + formatDateAxis(v, parseInt(daysToShow)) + } + /> + formatYAxis(v)} + type="number" + /> + + + +
+ ) : ( +
+ +

{t('account:no-data')}

+
+ )} + )} diff --git a/components/shared/DetailedAreaOrBarChart.tsx b/components/shared/DetailedAreaOrBarChart.tsx index d9db5266..de2b0af2 100644 --- a/components/shared/DetailedAreaOrBarChart.tsx +++ b/components/shared/DetailedAreaOrBarChart.tsx @@ -36,6 +36,8 @@ import useThemeWrapper from 'hooks/useThemeWrapper' dayjs.extend(relativeTime) +const titleClasses = 'mb-0.5 text-base' + interface DetailedAreaOrBarChartProps { chartType?: 'area' | 'bar' customTooltip?: ContentType @@ -149,8 +151,6 @@ const DetailedAreaOrBarChart: FunctionComponent< return 0 } - const titleClasses = `${small ? 'text-sm' : 'mb-0.5 text-base'} text-th-fgd-3` - return ( @@ -203,10 +203,8 @@ const DetailedAreaOrBarChart: FunctionComponent< {mouseData ? (
{animationSettings['number-scroll'] ? ( @@ -233,7 +231,7 @@ const DetailedAreaOrBarChart: FunctionComponent< )} {!hideChange ? ( - +
{animationSettings['number-scroll'] ? ( @@ -296,7 +292,7 @@ const DetailedAreaOrBarChart: FunctionComponent< )} {!hideChange ? ( - +