feat: migrate BrokerSummary, BrokerAssetCards and BrokerAccountOverviewPage
This commit is contained in:
parent
3682f43aa6
commit
ef97fd7136
@ -1,4 +1,6 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Box } from '@mui/material';
|
||||
import { Text } from '@moex-vibe/design-system';
|
||||
import { useBrokerOperations } from '@/entities/broker-operation';
|
||||
import { useBrokerAccountContext } from '@/widgets/broker-account-layout';
|
||||
import { BrokerAllocationChart } from '@/widgets/broker-allocation-chart';
|
||||
@ -11,16 +13,22 @@ export function BrokerAccountOverviewPage() {
|
||||
|
||||
if (portfolio.isLoading) return <BrokerOverviewSkeleton />;
|
||||
if (portfolio.error || !portfolio.data) {
|
||||
return <p role="alert">Не удалось загрузить сводку счёта</p>;
|
||||
return (
|
||||
<Text component="p" role="alert" tone="negative">
|
||||
Не удалось загрузить сводку счёта
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="broker-overview">
|
||||
<Box component="div" sx={{ display: 'grid', gap: 3 }}>
|
||||
<BrokerSummary portfolio={portfolio.data} />
|
||||
<BrokerAllocationChart portfolio={portfolio.data} />
|
||||
<BrokerAssetCards accountId={accountId} portfolio={portfolio.data} />
|
||||
{operations.error ? (
|
||||
<p role="alert">Не удалось загрузить последние операции</p>
|
||||
<Text component="p" role="alert" tone="negative">
|
||||
Не удалось загрузить последние операции
|
||||
</Text>
|
||||
) : (
|
||||
<BrokerOperationsTable
|
||||
title="Последние операции"
|
||||
@ -33,6 +41,6 @@ export function BrokerAccountOverviewPage() {
|
||||
page={operations.data}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Box } from '@mui/material';
|
||||
import { Text } from '@moex-vibe/design-system';
|
||||
import type { BrokerMoney, BrokerPortfolio } from '@/shared/api/responses';
|
||||
import { formatBrokerMoney, pluralize } from '@/shared/lib/formatters';
|
||||
|
||||
@ -11,6 +13,16 @@ function formatAllocationPercent(value: number | null) {
|
||||
return value === null ? '\u2014' : `${value.toFixed(1)}%`;
|
||||
}
|
||||
|
||||
const cardSx = {
|
||||
p: 2,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
borderRadius: 2,
|
||||
bgcolor: 'surface.default',
|
||||
display: 'grid',
|
||||
gap: 1,
|
||||
};
|
||||
|
||||
export function BrokerAssetCards({
|
||||
accountId,
|
||||
portfolio,
|
||||
@ -37,23 +49,23 @@ export function BrokerAssetCards({
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="broker-overview__assets" aria-label="Основные классы активов">
|
||||
<Box component="section" sx={{ display: 'grid', gap: 2 }} aria-label="Основные классы активов">
|
||||
{cards.map((card) => (
|
||||
<Link
|
||||
className="broker-overview__card broker-overview__asset-link"
|
||||
key={card.label}
|
||||
to={card.path}
|
||||
>
|
||||
<strong className="broker-overview__asset-title">{card.label}</strong>
|
||||
<span>
|
||||
{card.count} {card.countLabel}
|
||||
</span>
|
||||
<span>{formatBrokerMoney(card.value)}</span>
|
||||
<span>
|
||||
{formatAllocationPercent(allocationPercent(card.value, portfolio.totals.portfolio))}
|
||||
</span>
|
||||
<Link key={card.label} to={card.path}>
|
||||
<Box sx={{ ...cardSx, color: 'inherit', textDecoration: 'none' }}>
|
||||
<Box component="span" sx={{ color: 'primary.main', fontSize: 18, fontWeight: 700 }}>
|
||||
{card.label}
|
||||
</Box>
|
||||
<Text>
|
||||
{card.count} {card.countLabel}
|
||||
</Text>
|
||||
<Text>{formatBrokerMoney(card.value)}</Text>
|
||||
<Text>
|
||||
{formatAllocationPercent(allocationPercent(card.value, portfolio.totals.portfolio))}
|
||||
</Text>
|
||||
</Box>
|
||||
</Link>
|
||||
))}
|
||||
</section>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { Box } from '@mui/material';
|
||||
import { Text } from '@moex-vibe/design-system';
|
||||
import type { BrokerPortfolio } from '@/shared/api/responses';
|
||||
import {
|
||||
formatBrokerMoney as formatMoney,
|
||||
@ -6,31 +8,61 @@ import {
|
||||
|
||||
export function BrokerSummary({ portfolio }: { portfolio: BrokerPortfolio }) {
|
||||
return (
|
||||
<section className="broker-overview__summary" aria-label="Сводка счёта">
|
||||
<div className="broker-overview__card">
|
||||
<span className="broker-overview__label">Стоимость портфеля</span>
|
||||
<strong className="broker-overview__total">
|
||||
<Box component="section" sx={{ display: 'grid', gap: 2 }} aria-label="Сводка счёта">
|
||||
<Box
|
||||
sx={{
|
||||
p: 2,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
borderRadius: 2,
|
||||
bgcolor: 'surface.default',
|
||||
display: 'grid',
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<Text variant="label" tone="secondary">
|
||||
Стоимость портфеля
|
||||
</Text>
|
||||
<Box component="span" sx={{ fontWeight: 700, fontSize: 24 }}>
|
||||
{formatMoney(portfolio.totals.portfolio)}
|
||||
</strong>
|
||||
<span>За день: {formatMoney(portfolio.yields.daily)}</span>
|
||||
<span>Дневная доходность: {formatPercent(portfolio.yields.dailyPercent)}</span>
|
||||
<span>Ожидаемая доходность: {formatPercent(portfolio.yields.expectedPercent)}</span>
|
||||
</div>
|
||||
<div className="broker-overview__card">
|
||||
<span className="broker-overview__label">Денежный остаток</span>
|
||||
</Box>
|
||||
<Text>За день: {formatMoney(portfolio.yields.daily)}</Text>
|
||||
<Text>Дневная доходность: {formatPercent(portfolio.yields.dailyPercent)}</Text>
|
||||
<Text>Ожидаемая доходность: {formatPercent(portfolio.yields.expectedPercent)}</Text>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
p: 2,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
borderRadius: 2,
|
||||
bgcolor: 'surface.default',
|
||||
display: 'grid',
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<Text variant="label" tone="secondary">
|
||||
Денежный остаток
|
||||
</Text>
|
||||
{portfolio.cash.length === 0 ? (
|
||||
<span>Нет денежных остатков</span>
|
||||
<Text>Нет денежных остатков</Text>
|
||||
) : (
|
||||
<ul className="broker-overview__cash">
|
||||
<Box component="ul" sx={{ listStyle: 'none', display: 'grid', gap: 1 }}>
|
||||
{portfolio.cash.map((money, index) => (
|
||||
<li key={`${money.currency}-${index}`}>
|
||||
<span>{money.currency}</span>
|
||||
<strong>{formatMoney(money)}</strong>
|
||||
</li>
|
||||
<Box
|
||||
component="li"
|
||||
key={`${money.currency}-${index}`}
|
||||
sx={{ display: 'flex', justifyContent: 'space-between', gap: 1.5 }}
|
||||
>
|
||||
<Text>{money.currency}</Text>
|
||||
<Box component="span" sx={{ fontWeight: 700 }}>
|
||||
{formatMoney(money)}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</ul>
|
||||
</Box>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user