diff --git a/components/account/AccountChart.tsx b/components/account/AccountChart.tsx index 90434550..214fa937 100644 --- a/components/account/AccountChart.tsx +++ b/components/account/AccountChart.tsx @@ -55,6 +55,7 @@ const AccountChart = ({ daysToShow={daysToShow} hideChart={hideChart} loading={loading} + prefix="$" setDaysToShow={handleDaysToShow} tickFormat={(x) => `$${x.toFixed(2)}`} title={t(chartToShow)} diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index 585cef98..e3abd6a7 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -260,7 +260,7 @@ const AccountPage = () => { )}
- +

{t('today')}

@@ -451,7 +451,7 @@ const AccountPage = () => { {formatFixedDecimals(accountPnl, true)}

- +

{t('today')}

@@ -482,7 +482,7 @@ const AccountPage = () => { {formatFixedDecimals(interestTotalValue, true)}

- +

{t('today')}

diff --git a/components/shared/Change.tsx b/components/shared/Change.tsx index c0717430..956de750 100644 --- a/components/shared/Change.tsx +++ b/components/shared/Change.tsx @@ -4,12 +4,14 @@ import { DownTriangle, UpTriangle } from './DirectionTriangles' const Change = ({ change, - isCurrency, + prefix, size, + suffix, }: { change: number | typeof NaN - isCurrency?: boolean + prefix?: string size?: 'small' + suffix?: string }) => { return (
@@ -39,11 +41,11 @@ const Change = ({ : 'text-th-fgd-4' }`} > - {isCurrency ? '$' : ''} + {prefix ? prefix : ''} {isNaN(change) ? '0.00' : formatFixedDecimals(Math.abs(change), false, true)} - {!isCurrency ? '%' : ''} + {suffix ? suffix : ''}

) diff --git a/components/shared/DetailedAreaChart.tsx b/components/shared/DetailedAreaChart.tsx index c6589b8d..b53fd0a5 100644 --- a/components/shared/DetailedAreaChart.tsx +++ b/components/shared/DetailedAreaChart.tsx @@ -25,17 +25,22 @@ import useLocalStorageState from 'hooks/useLocalStorageState' import { ANIMATION_SETTINGS_KEY } from 'utils/constants' import { formatFixedDecimals } from 'utils/numbers' import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings' +import { AxisDomain } from 'recharts/types/util/types' dayjs.extend(relativeTime) interface DetailedAreaChartProps { data: any[] daysToShow?: string + domain?: AxisDomain hideChange?: boolean hideChart?: () => void loading?: boolean + prefix?: string setDaysToShow?: (x: string) => void - tickFormat?: (x: any) => string + small?: boolean + suffix?: string + tickFormat?: (x: number) => string title?: string xKey: string yKey: string @@ -52,10 +57,14 @@ export const formatDateAxis = (date: string, days: number) => { const DetailedAreaChart: FunctionComponent = ({ data, daysToShow = '1', + domain, hideChange, hideChart, loading, + prefix = '', setDaysToShow, + small, + suffix = '', tickFormat, title, xKey, @@ -81,7 +90,6 @@ const DetailedAreaChart: FunctionComponent = ({ const calculateChartChange = () => { if (data.length) { if (mouseData) { - console.log(mouseData) const index = data.findIndex((d: any) => d[xKey] === mouseData[xKey]) const change = index >= 0 ? data[index][yKey] - data[0][yKey] : 0 return isNaN(change) ? 0 : change @@ -112,66 +120,100 @@ const DetailedAreaChart: FunctionComponent = ({ ) : null}
-

{title}

+

+ {title} +

{mouseData ? (
-
+
{animationSettings['number-scroll'] ? ( ) : ( - {formatFixedDecimals(mouseData[yKey], true)} + {prefix + + formatFixedDecimals(mouseData[yKey]) + + suffix} )} {!hideChange ? ( ) : null}
-

+

{dayjs(mouseData[xKey]).format('DD MMM YY, h:mma')}

) : (
-
+
{animationSettings['number-scroll'] ? ( ) : ( - {formatFixedDecimals( - data[data.length - 1][yKey], - true - )} + {prefix + + formatFixedDecimals(data[data.length - 1][yKey]) + + suffix} )} {!hideChange ? ( ) : null}
-

+

{dayjs(data[data.length - 1][xKey]).format( 'DD MMM YY, h:mma' )} @@ -248,6 +290,7 @@ const DetailedAreaChart: FunctionComponent = ({ = ({ = ({ rounded = false, fillWidth = false, }) => { - const { t } = useTranslation(['common', 'swap', 'trade']) + const { t } = useTranslation(['common', 'swap', 'token', 'trade']) return (

{
- +
@@ -169,7 +169,7 @@ const MobileSpotMarketItem = ({ market }: { market: Serum3Market }) => {

{bank?.uiPrice ? formatFixedDecimals(bank.uiPrice, true) : '-'}

- +
diff --git a/components/stats/TokenStats.tsx b/components/stats/TokenStats.tsx index dd2a5459..4e0e8355 100644 --- a/components/stats/TokenStats.tsx +++ b/components/stats/TokenStats.tsx @@ -47,7 +47,9 @@ const TokenStats = () => { const router = useRouter() useEffect(() => { - actions.fetchTokenStats() + if (group && !tokenStats.length) { + actions.fetchTokenStats() + } }, [group]) const totalValues = useMemo(() => { @@ -128,6 +130,7 @@ const TokenStats = () => { }, ])} daysToShow={'999'} + prefix="$" tickFormat={(x) => `$${x.toFixed(2)}`} title={t('total-deposit-value')} xKey="date" @@ -152,7 +155,7 @@ const TokenStats = () => { }, ])} daysToShow={'999'} - // setDaysToShow={() => console.log('fuck')} + prefix="$" tickFormat={(x) => `$${x.toFixed(2)}`} title={t('total-borrow-value')} xKey="date" diff --git a/components/swap/SwapTokenChart.tsx b/components/swap/SwapTokenChart.tsx index eef31a71..91116841 100644 --- a/components/swap/SwapTokenChart.tsx +++ b/components/swap/SwapTokenChart.tsx @@ -198,7 +198,7 @@ const SwapTokenChart = () => { - +

@@ -227,7 +227,7 @@ const SwapTokenChart = () => { - +

diff --git a/components/trade/AdvancedMarketHeader.tsx b/components/trade/AdvancedMarketHeader.tsx index 7b45e34c..605f68ef 100644 --- a/components/trade/AdvancedMarketHeader.tsx +++ b/components/trade/AdvancedMarketHeader.tsx @@ -51,7 +51,7 @@ const AdvancedMarketHeader = () => {

{t('rolling-change')}
- +
{selectedMarket instanceof PerpMarket ? (
diff --git a/pages/token/[token].tsx b/pages/token/[token].tsx index 753e3d8c..b9818c10 100644 --- a/pages/token/[token].tsx +++ b/pages/token/[token].tsx @@ -1,6 +1,6 @@ import Change from '@components/shared/Change' import DailyRange from '@components/shared/DailyRange' -import mangoStore from '@store/mangoStore' +import mangoStore, { TokenStatsItem } from '@store/mangoStore' import type { NextPage } from 'next' import { useTranslation } from 'next-i18next' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' @@ -32,9 +32,14 @@ import { useCoingecko } from 'hooks/useCoingecko' import useLocalStorageState from 'hooks/useLocalStorageState' import { ANIMATION_SETTINGS_KEY } from 'utils/constants' import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings' +import TabButtons from '@components/shared/TabButtons' const PriceChart = dynamic(() => import('@components/token/PriceChart'), { ssr: false, }) +const DetailedAreaChart = dynamic( + () => import('@components/shared/DetailedAreaChart'), + { ssr: false } +) dayjs.extend(relativeTime) export async function getStaticProps({ locale }: { locale: string }) { @@ -73,6 +78,9 @@ const DEFAULT_COINGECKO_VALUES = { const Token: NextPage = () => { const { t } = useTranslation(['common', 'token']) + const actions = mangoStore((s) => s.actions) + const tokenStats = mangoStore((s) => s.tokenStats.data) + const loadingTokenStats = mangoStore((s) => s.tokenStats.loading) const [showFullDesc, setShowFullDesc] = useState(false) const [showDepositModal, setShowDepositModal] = useState(false) const [showBorrowModal, setShowBorrowModal] = useState(false) @@ -87,11 +95,35 @@ const Token: NextPage = () => { const [chartData, setChartData] = useState<{ prices: any[] } | null>(null) const [loadChartData, setLoadChartData] = useState(true) const [daysToShow, setDaysToShow] = useState('1') + const [activeDepositsTab, setActiveDepositsTab] = useState('token:deposits') + const [activeBorrowsTab, setActiveBorrowsTab] = useState('token:borrows') const [animationSettings] = useLocalStorageState( ANIMATION_SETTINGS_KEY, INITIAL_ANIMATION_SETTINGS ) + useEffect(() => { + if (group && !tokenStats.length) { + actions.fetchTokenStats() + } + }, [group]) + + const statsHistory = useMemo(() => { + if (!tokenStats.length) return [] + return tokenStats.reduce((a: TokenStatsItem[], c: TokenStatsItem) => { + if (c.symbol === token) { + const copy = { ...c } + copy.deposit_apr = copy.deposit_apr * 100 + copy.borrow_apr = copy.borrow_apr * 100 + a.push(copy) + } + return a.sort( + (a, b) => + new Date(a.date_hour).getTime() - new Date(b.date_hour).getTime() + ) + }, []) + }, [tokenStats]) + const bank = useMemo(() => { if (group && token) { const bank = group.banksMapByName.get(token.toString()) @@ -217,7 +249,7 @@ const Token: NextPage = () => {
{bank ? ( <> -
+
@@ -244,7 +276,7 @@ const Token: NextPage = () => { {formatFixedDecimals(bank.uiPrice, true)} )} {coingeckoData ? ( - + ) : null}
{coingeckoData ? ( @@ -306,53 +338,97 @@ const Token: NextPage = () => {
-
-
-

{t('token:lending')}

-
-

{t('total-deposits')}

-

- {formatFixedDecimals(bank.uiDeposits())} -

-
-
-

{t('token:total-value')}

-

- {formatFixedDecimals(bank.uiDeposits() * bank.uiPrice, true)} -

-
-
-

{t('deposit-rate')}

-

- {formatDecimal(bank.getDepositRateUi(), 2, { - fixed: true, - })} - % -

+
+
+
+ {statsHistory.length ? ( + <> + setActiveDepositsTab(v)} + showBorders + values={[ + ['token:deposits', 0], + ['token:deposit-rates', 0], + ]} + /> +
+ {activeDepositsTab === 'token:deposits' ? ( + x.toFixed(2)} + title={`${token} ${t('token:deposits')}`} + xKey="date_hour" + yKey={'total_deposits'} + /> + ) : ( + `${x.toFixed(2)}%`} + title={`${token} ${t('token:deposit-rates')} (APR)`} + xKey="date_hour" + yKey={'deposit_apr'} + /> + )} +
+ + ) : null}
-
-

{t('token:borrowing')}

-
-

{t('total-borrows')}

-

- {formatFixedDecimals(bank.uiBorrows())} -

-
-
-

{t('token:total-value')}

-

- {formatFixedDecimals(bank.uiBorrows() * bank.uiPrice, true)} -

-
-
-

{t('borrow-rate')}

-

- {formatDecimal(bank.getBorrowRateUi(), 2, { - fixed: true, - })} - % -

+
+
+ {statsHistory.length ? ( + <> + setActiveBorrowsTab(v)} + showBorders + values={[ + ['token:borrows', 0], + ['token:borrow-rates', 0], + ]} + /> +
+ {activeBorrowsTab === 'token:borrows' ? ( + x.toFixed(2)} + title={`${token} ${t('token:borrows')}`} + xKey="date_hour" + yKey={'total_borrows'} + /> + ) : ( + `${x.toFixed(2)}%`} + title={`${token} ${t('token:borrow-rates')} (APR)`} + xKey="date_hour" + yKey={'borrow_apr'} + /> + )} +
+ + ) : null}
@@ -426,8 +502,8 @@ const Token: NextPage = () => { ) : (
)} -
-
+
+

{bank.name} Stats

@@ -453,7 +529,7 @@ const Token: NextPage = () => { {formatFixedDecimals(ath.usd, true)} - +

{dayjs(ath_date.usd).format('MMM, D, YYYY')} ( @@ -461,14 +537,14 @@ const Token: NextPage = () => {

-
+

{t('token:all-time-low')}

{formatFixedDecimals(atl.usd, true)} - +

{dayjs(atl_date.usd).format('MMM, D, YYYY')} ( @@ -477,7 +553,7 @@ const Token: NextPage = () => {

-
+
{fully_diluted_valuation.usd ? (

{t('token:fdv')}

@@ -500,7 +576,7 @@ const Token: NextPage = () => {

{t('token:total-supply')}

diff --git a/public/locales/en/token.json b/public/locales/en/token.json index 617820ee..db1c6a5b 100644 --- a/public/locales/en/token.json +++ b/public/locales/en/token.json @@ -2,8 +2,12 @@ "all-time-high": "All-time High", "all-time-low": "All-time Low", "borrowing": "Borrowing", + "borrows": "Borrows", + "borrow-rates": "Borrow Rates", "chart-unavailable": "Chart Unavailable", "circulating-supply": "Circulating Supply", + "deposits": "Deposits", + "deposit-rates": "Deposit Rates", "fdv": "Fully Diluted Value", "go-to-account": "Go To Account", "lending": "Lending", diff --git a/public/locales/es/token.json b/public/locales/es/token.json index 617820ee..db1c6a5b 100644 --- a/public/locales/es/token.json +++ b/public/locales/es/token.json @@ -2,8 +2,12 @@ "all-time-high": "All-time High", "all-time-low": "All-time Low", "borrowing": "Borrowing", + "borrows": "Borrows", + "borrow-rates": "Borrow Rates", "chart-unavailable": "Chart Unavailable", "circulating-supply": "Circulating Supply", + "deposits": "Deposits", + "deposit-rates": "Deposit Rates", "fdv": "Fully Diluted Value", "go-to-account": "Go To Account", "lending": "Lending", diff --git a/public/locales/ru/token.json b/public/locales/ru/token.json index 617820ee..db1c6a5b 100644 --- a/public/locales/ru/token.json +++ b/public/locales/ru/token.json @@ -2,8 +2,12 @@ "all-time-high": "All-time High", "all-time-low": "All-time Low", "borrowing": "Borrowing", + "borrows": "Borrows", + "borrow-rates": "Borrow Rates", "chart-unavailable": "Chart Unavailable", "circulating-supply": "Circulating Supply", + "deposits": "Deposits", + "deposit-rates": "Deposit Rates", "fdv": "Fully Diluted Value", "go-to-account": "Go To Account", "lending": "Lending", diff --git a/public/locales/zh/token.json b/public/locales/zh/token.json index 617820ee..db1c6a5b 100644 --- a/public/locales/zh/token.json +++ b/public/locales/zh/token.json @@ -2,8 +2,12 @@ "all-time-high": "All-time High", "all-time-low": "All-time Low", "borrowing": "Borrowing", + "borrows": "Borrows", + "borrow-rates": "Borrow Rates", "chart-unavailable": "Chart Unavailable", "circulating-supply": "Circulating Supply", + "deposits": "Deposits", + "deposit-rates": "Deposit Rates", "fdv": "Fully Diluted Value", "go-to-account": "Go To Account", "lending": "Lending", diff --git a/public/locales/zh_tw/token.json b/public/locales/zh_tw/token.json index 617820ee..db1c6a5b 100644 --- a/public/locales/zh_tw/token.json +++ b/public/locales/zh_tw/token.json @@ -2,8 +2,12 @@ "all-time-high": "All-time High", "all-time-low": "All-time Low", "borrowing": "Borrowing", + "borrows": "Borrows", + "borrow-rates": "Borrow Rates", "chart-unavailable": "Chart Unavailable", "circulating-supply": "Circulating Supply", + "deposits": "Deposits", + "deposit-rates": "Deposit Rates", "fdv": "Fully Diluted Value", "go-to-account": "Go To Account", "lending": "Lending", diff --git a/tailwind.config.js b/tailwind.config.js index 4a30a7cf..14665d48 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -253,7 +253,7 @@ module.exports = { }, button: { DEFAULT: 'hsl(156, 55%, 26%)', - hover: 'hsl(202, 5%, 40%)', + hover: 'hsl(156, 55%, 21%)', }, link: { DEFAULT: 'hsl(31, 100%, 57%)', hover: 'hsl(31, 100%, 42%)' }, down: {