better chart empty states

This commit is contained in:
saml33 2023-12-03 23:27:49 +11:00
parent 8e27126d63
commit ca94ea07d0
8 changed files with 471 additions and 442 deletions

View File

@ -19,6 +19,27 @@ import Button from '@components/shared/Button'
const EMPTY_STATE_WRAPPER_CLASSES =
'flex h-[180px] flex-col justify-center pb-4 md:h-full'
const DEFAULT_CHART_DATA = [
{
account_equity: 0,
time: dayjs().subtract(1, 'hour').toISOString(),
borrow_interest_cumulative_usd: 0,
deposit_interest_cumulative_usd: 0,
pnl: 0,
spot_value: 0,
transfer_balance: 0,
},
{
account_equity: 0,
time: dayjs().toISOString(),
borrow_interest_cumulative_usd: 0,
deposit_interest_cumulative_usd: 0,
pnl: 0,
spot_value: 0,
transfer_balance: 0,
},
]
const AccountOverview = () => {
const { t } = useTranslation(['common', 'governance'])
const { group } = useMangoGroup()
@ -35,12 +56,12 @@ const AccountOverview = () => {
}, [group, mangoAccount])
const latestAccountData = useMemo(() => {
if (!accountValue || !performanceData || !performanceData.length) return []
if (!performanceData || !performanceData?.length) return []
const latestDataItem = performanceData[performanceData.length - 1]
return [
{
account_equity: accountValue,
time: dayjs(Date.now()).toISOString(),
time: dayjs().toISOString(),
borrow_interest_cumulative_usd:
latestDataItem.borrow_interest_cumulative_usd,
deposit_interest_cumulative_usd:
@ -52,8 +73,13 @@ const AccountOverview = () => {
]
}, [accountValue, performanceData])
const chartData =
performanceData && performanceData?.length ? performanceData : []
const chartData = useMemo(() => {
if (performanceData && performanceData?.length)
return performanceData.concat(latestAccountData)
if (!latestAccountData.length) {
return DEFAULT_CHART_DATA
}
}, [latestAccountData, performanceData])
return (
<>
@ -64,7 +90,7 @@ const AccountOverview = () => {
<div className="px-4 pb-4 md:px-6">
<DetailedAreaOrBarChart
changeAsPercent
data={chartData.concat(latestAccountData)}
data={chartData}
daysToShow={daysToShow}
setDaysToShow={setDaysToShow}
loading={loadingPerformanceData || initialLoad}

View File

@ -129,7 +129,7 @@ const AccountStats = ({ hideView }: { hideView: () => void }) => {
</Tooltip>
{loadingFunding && mangoAccountAddress ? (
<SheenLoader className="mt-2">
<div className="h-7 w-16 bg-th-bkg-2" />
<div className="h-[26px] w-16 bg-th-bkg-2" />
</SheenLoader>
) : (
<p className="mt-0.5 text-2xl font-bold text-th-fgd-1">
@ -142,7 +142,7 @@ const AccountStats = ({ hideView }: { hideView: () => void }) => {
</p>
)}
</div>
<div className="px-6 py-4">
<div className="px-6 py-4 lg:py-6">
<FundingChart />
</div>
</div>
@ -153,7 +153,7 @@ const AccountStats = ({ hideView }: { hideView: () => void }) => {
</p>
{loadingVolumeTotalData && mangoAccountAddress ? (
<SheenLoader className="mt-2">
<div className="h-7 w-16 bg-th-bkg-2" />
<div className="h-[26px] w-16 bg-th-bkg-2" />
</SheenLoader>
) : (
<p className="mt-0.5 text-2xl font-bold text-th-fgd-1">

View File

@ -19,12 +19,7 @@ import FlipNumbers from 'react-flip-numbers'
import ContentBox from './ContentBox'
import SheenLoader from './SheenLoader'
import { COLORS } from '../../styles/colors'
import { IconButton } from './Button'
import {
ArrowLeftIcon,
ArrowsRightLeftIcon,
NoSymbolIcon,
} from '@heroicons/react/20/solid'
import { ArrowsRightLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
import { FadeInFadeOut } from './Transitions'
import ChartRangeButtons from './ChartRangeButtons'
import Change from './Change'
@ -57,7 +52,6 @@ interface DetailedAreaOrBarChartProps {
domain?: AxisDomain
heightClass?: string
hideChange?: boolean
hideChart?: () => void
hideAxis?: boolean
isPrivate?: boolean
loaderHeightClass?: string
@ -98,7 +92,6 @@ const DetailedAreaOrBarChart: FunctionComponent<
domain,
heightClass,
hideChange,
hideChart,
hideAxis,
isPrivate,
loaderHeightClass,
@ -203,7 +196,7 @@ const DetailedAreaOrBarChart: FunctionComponent<
} w-full rounded-lg bg-th-bkg-2`}
/>
</SheenLoader>
) : filteredData.length ? (
) : (
<div className="relative">
{setDaysToShow ? (
<div className="mb-4 sm:absolute sm:-top-1 sm:right-0 sm:mb-0 sm:flex sm:justify-end">
@ -215,443 +208,448 @@ const DetailedAreaOrBarChart: FunctionComponent<
/>
</div>
) : null}
<div className="flex items-start justify-between">
<div className="flex flex-col md:flex-row md:items-start md:space-x-6">
{hideChart ? (
<IconButton
className="mb-6"
onClick={hideChart}
size="medium"
{title ? (
tooltipContent ? (
<Tooltip content={tooltipContent}>
<p
className={`${titleClasses}
tooltip-underline`}
>
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
) : null}
<div>
{title ? (
tooltipContent ? (
<Tooltip content={tooltipContent}>
<p
className={`${titleClasses}
tooltip-underline`}
>
{title}
</p>
</Tooltip>
) : (
<p className={titleClasses}>{title}</p>
)
) : null}
{mouseData ? (
{title}
</p>
</Tooltip>
) : (
<p className={titleClasses}>{title}</p>
)
) : null}
{filteredData.length ? (
<>
<div className="flex items-start justify-between">
<div className="flex flex-col md:flex-row md:items-start md:space-x-6">
<div>
<div
className={`flex items-end ${
small ? 'h-8 text-2xl' : 'mb-1 text-4xl'
} font-display text-th-fgd-1`}
>
{animationSettings['number-scroll'] ? (
isPrivate && privacyMode ? (
<span>{PRIVATE_MODE_STRING}</span>
) : (
<FlipNumbers
height={small ? 24 : 40}
width={small ? 17 : 30}
play
numbers={`${
mouseData[yKey] < 0 ? '-' : ''
}${prefix}${formatNumericValue(
Math.abs(mouseData[yKey]),
yDecimals,
)}${suffix}`}
/>
)
) : (
<span className="tabular-nums">
{mouseData[yKey] < 0 ? '-' : ''}
{prefix}
<FormatNumericValue
value={Math.abs(mouseData[yKey])}
decimals={yDecimals}
isPrivate={isPrivate}
/>
{suffix}
</span>
)}
{!hideChange ? (
{mouseData ? (
<div>
<div
className={`ml-3 flex items-center ${
small ? 'mb-[3px]' : 'mb-0.5'
}`}
className={`flex items-end ${
small ? 'h-8 text-2xl' : 'mb-1 text-4xl'
} font-display text-th-fgd-1`}
>
<Change
change={calculateChartChange()}
decimals={!showChangePercentage ? yDecimals : 2}
prefix={!showChangePercentage ? prefix : ''}
suffix={!showChangePercentage ? suffix : '%'}
isPrivate={isPrivate}
/>
{changeAsPercent ? (
<ToggleChangeTypeButton
changeType={showChangePercentage}
setChangeType={setShowChangePercentage}
/>
{animationSettings['number-scroll'] ? (
isPrivate && privacyMode ? (
<span>{PRIVATE_MODE_STRING}</span>
) : (
<FlipNumbers
height={small ? 24 : 40}
width={small ? 17 : 30}
play
numbers={`${
mouseData[yKey] < 0 ? '-' : ''
}${prefix}${formatNumericValue(
Math.abs(mouseData[yKey]),
yDecimals,
)}${suffix}`}
/>
)
) : (
<span className="tabular-nums">
{mouseData[yKey] < 0 ? '-' : ''}
{prefix}
<FormatNumericValue
value={Math.abs(mouseData[yKey])}
decimals={yDecimals}
isPrivate={isPrivate}
/>
{suffix}
</span>
)}
{!hideChange ? (
<div
className={`ml-3 flex items-center ${
small ? 'mb-[3px]' : 'mb-0.5'
}`}
>
<Change
change={calculateChartChange()}
decimals={
!showChangePercentage ? yDecimals : 2
}
prefix={!showChangePercentage ? prefix : ''}
suffix={!showChangePercentage ? suffix : '%'}
isPrivate={isPrivate}
/>
{changeAsPercent ? (
<ToggleChangeTypeButton
changeType={showChangePercentage}
setChangeType={setShowChangePercentage}
/>
) : null}
</div>
) : null}
</div>
) : null}
</div>
<p
className={`${
small ? 'text-xs' : 'text-sm'
} text-th-fgd-4`}
>
{formatXKeyHeading
? formatXKeyHeading(mouseData[xKey])
: dayjs(mouseData[xKey]).format(
tooltipDateFormat
? tooltipDateFormat
: 'DD MMM YY, h:mma',
)}
</p>
</div>
) : (
<div>
<div
className={`flex items-end ${
small ? 'h-8 text-2xl' : 'mb-1 text-4xl'
} font-display text-th-fgd-1`}
>
{animationSettings['number-scroll'] ? (
isPrivate && privacyMode ? (
<span>{PRIVATE_MODE_STRING}</span>
) : (
<FlipNumbers
height={small ? 24 : 40}
width={small ? 17 : 30}
play
numbers={`${
filteredData[filteredData.length - 1][yKey] < 0
<p
className={`${
small ? 'text-xs' : 'text-sm'
} text-th-fgd-4`}
>
{formatXKeyHeading
? formatXKeyHeading(mouseData[xKey])
: dayjs(mouseData[xKey]).format(
tooltipDateFormat
? tooltipDateFormat
: 'DD MMM YY, h:mma',
)}
</p>
</div>
) : (
<div>
<div
className={`flex items-end ${
small ? 'h-8 text-2xl' : 'mb-1 text-4xl'
} font-display text-th-fgd-1`}
>
{animationSettings['number-scroll'] ? (
isPrivate && privacyMode ? (
<span>{PRIVATE_MODE_STRING}</span>
) : (
<FlipNumbers
height={small ? 24 : 40}
width={small ? 17 : 30}
play
numbers={`${
filteredData[filteredData.length - 1][
yKey
] < 0
? '-'
: ''
}${prefix}${formatNumericValue(
Math.abs(
filteredData[filteredData.length - 1][
yKey
],
),
yDecimals,
)}${suffix}`}
/>
)
) : (
<span>
{filteredData[filteredData.length - 1][yKey] < 0
? '-'
: ''
}${prefix}${formatNumericValue(
Math.abs(
filteredData[filteredData.length - 1][yKey],
),
yDecimals,
)}${suffix}`}
/>
)
) : (
<span>
{filteredData[filteredData.length - 1][yKey] < 0
? '-'
: ''}
{prefix}
<span className="tabular-nums">
<FormatNumericValue
value={
data
? Math.abs(data[data.length - 1][yKey])
: 0
}
decimals={yDecimals}
isPrivate={isPrivate}
/>
</span>
{suffix}
</span>
)}
{!hideChange ? (
<div
className={`ml-3 flex items-center ${
small ? 'mb-[3px]' : 'mb-0.5'
}`}
>
<Change
change={calculateChartChange()}
decimals={!showChangePercentage ? yDecimals : 2}
prefix={!showChangePercentage ? prefix : ''}
suffix={!showChangePercentage ? suffix : '%'}
isPrivate={isPrivate}
/>
{changeAsPercent ? (
<ToggleChangeTypeButton
changeType={showChangePercentage}
setChangeType={setShowChangePercentage}
/>
: ''}
{prefix}
<span className="tabular-nums">
<FormatNumericValue
value={
data
? Math.abs(data[data.length - 1][yKey])
: 0
}
decimals={yDecimals}
isPrivate={isPrivate}
/>
</span>
{suffix}
</span>
)}
{!hideChange ? (
<div
className={`ml-3 flex items-center ${
small ? 'mb-[3px]' : 'mb-0.5'
}`}
>
<Change
change={calculateChartChange()}
decimals={
!showChangePercentage ? yDecimals : 2
}
prefix={!showChangePercentage ? prefix : ''}
suffix={!showChangePercentage ? suffix : '%'}
isPrivate={isPrivate}
/>
{changeAsPercent ? (
<ToggleChangeTypeButton
changeType={showChangePercentage}
setChangeType={setShowChangePercentage}
/>
) : null}
</div>
) : null}
</div>
) : null}
</div>
<p
className={`${
small ? 'text-xs' : 'text-sm'
} text-th-fgd-4`}
>
{formatXKeyHeading
? formatXKeyHeading(
filteredData[filteredData.length - 1][xKey],
)
: dayjs(
filteredData[filteredData.length - 1][xKey],
).format(
tooltipDateFormat
? tooltipDateFormat
: 'DD MMM YY, h:mma',
)}
</p>
<p
className={`${
small ? 'text-xs' : 'text-sm'
} text-th-fgd-4`}
>
{formatXKeyHeading
? formatXKeyHeading(
filteredData[filteredData.length - 1][xKey],
)
: dayjs(
filteredData[filteredData.length - 1][xKey],
).format(
tooltipDateFormat
? tooltipDateFormat
: 'DD MMM YY, h:mma',
)}
</p>
</div>
)}
</div>
)}
</div>
</div>
<div
className={`-mt-1 ${
heightClass ? heightClass : 'h-96'
} w-auto`}
>
<div className="-mx-6 mt-6 h-full">
<ResponsiveContainer width="100%" height="100%">
{chartType === 'area' ? (
<AreaChart
data={filteredData}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<RechartsTooltip
cursor={{
strokeOpacity: 0.09,
}}
content={customTooltip ? customTooltip : <></>}
/>
<defs>
<linearGradient
id={`gradientArea-${title?.replace(
/[^a-zA-Z]/g,
'',
)}`}
x1="0"
y1={flipGradientCoords ? '1' : '0'}
x2="0"
y2={flipGradientCoords ? '0' : '1'}
>
<stop
offset="0%"
stopColor={
calculateChartChange() >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
stopOpacity={0.15}
/>
<stop
offset="99%"
stopColor={
calculateChartChange() >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
stopOpacity={0}
/>
</linearGradient>
</defs>
<Area
isAnimationActive={false}
type="monotone"
dataKey={yKey}
stroke={
isNaN(calculateChartChange())
? COLORS.FGD4[theme]
: calculateChartChange() >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
strokeWidth={1.5}
fill={`url(#gradientArea-${title?.replace(
/[^a-zA-Z]/g,
'',
)})`}
/>
<XAxis
axisLine={false}
dataKey={xKey}
hide={hideAxis}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={
xAxisType !== 'number'
? (d) => formatDateAxis(d, parseInt(daysToShow))
: undefined
}
type={xAxisType}
>
{xAxisLabel ? (
<Label
value={xAxisLabel}
offset={-2}
position="insideBottom"
fontSize={10}
fill="var(--fgd-3)"
/>
) : null}
</XAxis>
<YAxis
axisLine={false}
dataKey={yKey}
hide={hideAxis}
minTickGap={20}
type="number"
domain={
domain
? domain
: ([dataMin, dataMax]) => {
const difference = dataMax - dataMin
if (difference < 0.01) {
return [dataMin - 0.001, dataMax + 0.001]
} else if (difference < 0.1) {
return [dataMin - 0.01, dataMax + 0.01]
} else if (difference < 1) {
return [dataMin - 0.1, dataMax + 0.11]
} else if (difference < 10) {
return [dataMin - 1, dataMax + 1]
} else {
return [dataMin, dataMax]
}
}
}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickFormatter={
tickFormat ? (v) => tickFormat(v) : undefined
}
tickLine={false}
/>
{showZeroLine ? (
<ReferenceLine
y={0}
stroke="var(--fgd-4)"
strokeDasharray="2 2"
/>
) : null}
</AreaChart>
) : (
<BarChart
data={filteredData}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<RechartsTooltip
cursor={{
fill: 'var(--bkg-2)',
opacity: 0.5,
}}
content={customTooltip ? customTooltip : <></>}
/>
<defs>
<linearGradient
id="greenGradientBar"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="0%"
stopColor={COLORS.UP[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.UP[theme]}
stopOpacity={0.7}
/>
</linearGradient>
<linearGradient
id="redGradientBar"
x1="0"
y1="1"
x2="0"
y2="0"
>
<stop
offset="0%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={0.7}
/>
</linearGradient>
</defs>
<Bar dataKey={yKey}>
{filteredData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={
entry[yKey] > 0
? 'url(#greenGradientBar)'
: 'url(#redGradientBar)'
}
/>
)
})}
</Bar>
<XAxis
dataKey={xKey}
axisLine={false}
dy={10}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) =>
formatDateAxis(v, parseInt(daysToShow))
}
/>
<YAxis
dataKey={yKey}
interval="preserveStartEnd"
axisLine={false}
dx={-10}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={
tickFormat ? (v) => tickFormat(v) : undefined
}
type="number"
/>
<ReferenceLine y={0} stroke={COLORS.BKG4[theme]} />
</BarChart>
)}
</ResponsiveContainer>
</div>
</div>
</>
) : (
<div
className={`flex ${
heightClass ? heightClass : 'h-96'
} mt-4 items-center justify-center rounded-lg border border-th-bkg-3 p-8 text-th-fgd-3`}
>
<div>
<NoSymbolIcon className="mx-auto mb-1 h-6 w-6 text-th-fgd-4" />
<p className="text-th-fgd-3">{t('no-data')}</p>
</div>
</div>
</div>
<div
className={`-mt-1 ${heightClass ? heightClass : 'h-96'} w-auto`}
>
<div className="-mx-6 mt-6 h-full">
<ResponsiveContainer width="100%" height="100%">
{chartType === 'area' ? (
<AreaChart
data={filteredData}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<RechartsTooltip
cursor={{
strokeOpacity: 0.09,
}}
content={customTooltip ? customTooltip : <></>}
/>
<defs>
<linearGradient
id={`gradientArea-${title?.replace(
/[^a-zA-Z]/g,
'',
)}`}
x1="0"
y1={flipGradientCoords ? '1' : '0'}
x2="0"
y2={flipGradientCoords ? '0' : '1'}
>
<stop
offset="0%"
stopColor={
calculateChartChange() >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
stopOpacity={0.15}
/>
<stop
offset="99%"
stopColor={
calculateChartChange() >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
stopOpacity={0}
/>
</linearGradient>
</defs>
<Area
isAnimationActive={false}
type="monotone"
dataKey={yKey}
stroke={
isNaN(calculateChartChange())
? COLORS.FGD4[theme]
: calculateChartChange() >= 0
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
strokeWidth={1.5}
fill={`url(#gradientArea-${title?.replace(
/[^a-zA-Z]/g,
'',
)})`}
/>
<XAxis
axisLine={false}
dataKey={xKey}
hide={hideAxis}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={
xAxisType !== 'number'
? (d) => formatDateAxis(d, parseInt(daysToShow))
: undefined
}
type={xAxisType}
>
{xAxisLabel ? (
<Label
value={xAxisLabel}
offset={-2}
position="insideBottom"
fontSize={10}
fill="var(--fgd-3)"
/>
) : null}
</XAxis>
<YAxis
axisLine={false}
dataKey={yKey}
hide={hideAxis}
minTickGap={20}
type="number"
domain={
domain
? domain
: ([dataMin, dataMax]) => {
const difference = dataMax - dataMin
if (difference < 0.01) {
return [dataMin - 0.001, dataMax + 0.001]
} else if (difference < 0.1) {
return [dataMin - 0.01, dataMax + 0.01]
} else if (difference < 1) {
return [dataMin - 0.1, dataMax + 0.11]
} else if (difference < 10) {
return [dataMin - 1, dataMax + 1]
} else {
return [dataMin, dataMax]
}
}
}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickFormatter={
tickFormat ? (v) => tickFormat(v) : undefined
}
tickLine={false}
/>
{showZeroLine ? (
<ReferenceLine
y={0}
stroke="var(--fgd-4)"
strokeDasharray="2 2"
/>
) : null}
</AreaChart>
) : (
<BarChart
data={filteredData}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<RechartsTooltip
cursor={{
fill: 'var(--bkg-2)',
opacity: 0.5,
}}
content={customTooltip ? customTooltip : <></>}
/>
<defs>
<linearGradient
id="greenGradientBar"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="0%"
stopColor={COLORS.UP[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.UP[theme]}
stopOpacity={0.7}
/>
</linearGradient>
<linearGradient
id="redGradientBar"
x1="0"
y1="1"
x2="0"
y2="0"
>
<stop
offset="0%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={0.7}
/>
</linearGradient>
</defs>
<Bar dataKey={yKey}>
{filteredData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={
entry[yKey] > 0
? 'url(#greenGradientBar)'
: 'url(#redGradientBar)'
}
/>
)
})}
</Bar>
<XAxis
dataKey={xKey}
axisLine={false}
dy={10}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) =>
formatDateAxis(v, parseInt(daysToShow))
}
/>
<YAxis
dataKey={yKey}
interval="preserveStartEnd"
axisLine={false}
dx={-10}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={
tickFormat ? (v) => tickFormat(v) : undefined
}
type="number"
/>
<ReferenceLine y={0} stroke={COLORS.BKG4[theme]} />
</BarChart>
)}
</ResponsiveContainer>
</div>
</div>
</div>
) : (
<div
className={`flex ${
heightClass ? heightClass : 'h-96'
} items-center justify-center p-4 text-th-fgd-3`}
>
<div>
<NoSymbolIcon className="mx-auto mb-1 h-6 w-6 text-th-fgd-4" />
<p className="text-th-fgd-4">{t('chart-unavailable')}</p>
</div>
)}
</div>
)}
</ContentBox>

View File

@ -129,6 +129,7 @@
"new-version": "New version available",
"nft-market": "NFT Market",
"no": "No",
"no-data": "No data to display",
"offchain-services": "Offchain Services",
"open-account": "Open New Account",
"operational": "Operational",

View File

@ -129,6 +129,7 @@
"new-version": "New version available",
"nft-market": "NFT Market",
"no": "No",
"no-data": "No data to display",
"offchain-services": "Offchain Services",
"open-account": "Open New Account",
"operational": "Operational",

View File

@ -129,6 +129,7 @@
"new-version": "New version available",
"nft-market": "NFT Market",
"no": "No",
"no-data": "No data to display",
"offchain-services": "Offchain Services",
"open-account": "Open New Account",
"operational": "Operational",

View File

@ -128,6 +128,7 @@
"new-version": "新版本出来了",
"nft-market": "NFT Market",
"no": "不",
"no-data": "无数据可显示",
"offchain-services": "区块联外的服务",
"open-account": "Open New Account",
"operational": "运行中",

View File

@ -128,6 +128,7 @@
"new-version": "新版本出來了",
"nft-market": "NFT Market",
"no": "不",
"no-data": "無數據可顯示",
"offchain-services": "區塊聯外的服務",
"open-account": "Open New Account",
"operational": "運行中",