refactor(frontend): deduplicate analytics metric cells and restore text states
This commit is contained in:
parent
d7b65e256f
commit
58b8075583
@ -1,4 +1,4 @@
|
||||
import { Metric } from '@moex-vibe/design-system'
|
||||
import { Metric, Text } from '@moex-vibe/design-system'
|
||||
import { Box } from '@mui/material'
|
||||
import type { BrokerAnalytics } from '@/shared/api'
|
||||
import {
|
||||
@ -17,6 +17,19 @@ type AnalyticsField =
|
||||
| 'totalCoupons'
|
||||
| 'totalReceived'
|
||||
|
||||
const ANALYTICS_METRICS: readonly {
|
||||
field: AnalyticsField
|
||||
label: string
|
||||
testId: string
|
||||
}[] = [
|
||||
{ field: 'totalDeposits', label: 'Пополнения', testId: 'dashboard-analytics-totalDeposits' },
|
||||
{ field: 'totalWithdrawn', label: 'Выводы', testId: 'dashboard-analytics-totalWithdrawn' },
|
||||
{ field: 'netInvested', label: 'Нетто', testId: 'dashboard-analytics-netInvested' },
|
||||
{ field: 'totalDividends', label: 'Дивиденды', testId: 'dashboard-analytics-totalDividends' },
|
||||
{ field: 'totalCoupons', label: 'Купоны', testId: 'dashboard-analytics-totalCoupons' },
|
||||
{ field: 'totalReceived', label: 'Всего получено', testId: 'dashboard-analytics-totalReceived' },
|
||||
]
|
||||
|
||||
function analyticsTone(field: AnalyticsField, value: number): MoneyTone {
|
||||
if (field === 'totalWithdrawn') {
|
||||
return value > 0 ? 'negative' : moneyTone(value)
|
||||
@ -40,13 +53,13 @@ export function BrokerDashboardAnalyticsCard({
|
||||
isError: boolean
|
||||
}) {
|
||||
return (
|
||||
<BrokerDashboardCard title="Аналитика доходности" ariaLabel="Аналитика доходности">
|
||||
<BrokerDashboardCard title="Аналитика доходности">
|
||||
{isError ? (
|
||||
<Metric label="Ошибка" value="Не удалось загрузить аналитику" />
|
||||
<Text tone="negative">Не удалось загрузить аналитику</Text>
|
||||
) : isLoading ? (
|
||||
<Metric label="Загрузка" value="Загрузка аналитики…" />
|
||||
<Text tone="muted">Загрузка аналитики…</Text>
|
||||
) : !data ? (
|
||||
<Metric label="Нет данных" value="Нет данных для аналитики" />
|
||||
<Text tone="muted">Нет данных для аналитики</Text>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
@ -55,102 +68,26 @@ export function BrokerDashboardAnalyticsCard({
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<Metric
|
||||
label="Пополнения"
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid="dashboard-analytics-totalDeposits"
|
||||
data-tone={analyticsTone('totalDeposits', data.totalDeposits)}
|
||||
sx={{
|
||||
color: moneyToneToColor(analyticsTone('totalDeposits', data.totalDeposits)),
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{analyticsDisplay('totalDeposits', data.totalDeposits, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Metric
|
||||
label="Выводы"
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid="dashboard-analytics-totalWithdrawn"
|
||||
data-tone={analyticsTone('totalWithdrawn', data.totalWithdrawn)}
|
||||
sx={{
|
||||
color: moneyToneToColor(analyticsTone('totalWithdrawn', data.totalWithdrawn)),
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{analyticsDisplay('totalWithdrawn', data.totalWithdrawn, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Metric
|
||||
label="Нетто"
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid="dashboard-analytics-netInvested"
|
||||
data-tone={analyticsTone('netInvested', data.netInvested)}
|
||||
sx={{
|
||||
color: moneyToneToColor(analyticsTone('netInvested', data.netInvested)),
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{analyticsDisplay('netInvested', data.netInvested, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Metric
|
||||
label="Дивиденды"
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid="dashboard-analytics-totalDividends"
|
||||
data-tone={analyticsTone('totalDividends', data.totalDividends)}
|
||||
sx={{
|
||||
color: moneyToneToColor(analyticsTone('totalDividends', data.totalDividends)),
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{analyticsDisplay('totalDividends', data.totalDividends, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Metric
|
||||
label="Купоны"
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid="dashboard-analytics-totalCoupons"
|
||||
data-tone={analyticsTone('totalCoupons', data.totalCoupons)}
|
||||
sx={{
|
||||
color: moneyToneToColor(analyticsTone('totalCoupons', data.totalCoupons)),
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{analyticsDisplay('totalCoupons', data.totalCoupons, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Metric
|
||||
label="Всего получено"
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid="dashboard-analytics-totalReceived"
|
||||
data-tone={analyticsTone('totalReceived', data.totalReceived)}
|
||||
sx={{
|
||||
color: moneyToneToColor(analyticsTone('totalReceived', data.totalReceived)),
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{analyticsDisplay('totalReceived', data.totalReceived, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
{ANALYTICS_METRICS.map(({ field, label, testId }) => {
|
||||
const value = data[field]
|
||||
const tone = analyticsTone(field, value)
|
||||
return (
|
||||
<Metric
|
||||
key={field}
|
||||
label={label}
|
||||
value={
|
||||
<Box
|
||||
component="span"
|
||||
data-testid={testId}
|
||||
data-tone={tone}
|
||||
sx={{ color: moneyToneToColor(tone), fontWeight: 700 }}
|
||||
>
|
||||
{analyticsDisplay(field, value, data.currency)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
</BrokerDashboardCard>
|
||||
|
||||
@ -19,10 +19,11 @@ export function BrokerDashboardCard({
|
||||
sx,
|
||||
ariaLabel,
|
||||
}: BrokerDashboardCardProps) {
|
||||
const resolvedAriaLabel = ariaLabel ?? title
|
||||
return (
|
||||
<Box
|
||||
component="section"
|
||||
aria-label={ariaLabel}
|
||||
aria-label={resolvedAriaLabel}
|
||||
sx={{
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user