- Delete shared/api/responses.ts, move type re-exports to index.ts - Update all 55+ imports from shared/api/responses to shared/api - Delete stale client.test.ts (tested deleted client.ts) - Run biome checks and fix import ordering - Update tasks.md and plan.md to reflect actual approach
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import type { PortfolioSummary } from '@/shared/api'
|
||
|
||
export function AnalyticsSummary({ summary }: { summary: PortfolioSummary }) {
|
||
const formatRub = (val: number | null) =>
|
||
val != null
|
||
? val.toLocaleString('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||
: '—'
|
||
|
||
const formatPct = (val: number | null) => (val != null ? `${val.toFixed(2)}%` : '—')
|
||
|
||
const pnlColor =
|
||
summary.totalPnl > 0
|
||
? 'var(--color-positive)'
|
||
: summary.totalPnl < 0
|
||
? 'var(--color-negative)'
|
||
: 'inherit'
|
||
|
||
return (
|
||
<div
|
||
style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))',
|
||
gap: 24,
|
||
padding: 20,
|
||
background: 'var(--color-surface)',
|
||
border: '1px solid #e0e0e0',
|
||
borderRadius: 'var(--border-radius)',
|
||
marginTop: 16,
|
||
}}
|
||
>
|
||
<div>
|
||
<div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 4 }}>
|
||
Инвестировано
|
||
</div>
|
||
<div style={{ fontSize: 18, fontWeight: 700 }}>{formatRub(summary.totalInvested)}</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 4 }}>
|
||
Текущая стоимость
|
||
</div>
|
||
<div style={{ fontSize: 18, fontWeight: 700 }}>{formatRub(summary.totalValue)}</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 4 }}>
|
||
Прибыль/Убыток
|
||
</div>
|
||
<div style={{ fontSize: 18, fontWeight: 700, color: pnlColor }}>
|
||
{summary.totalPnl > 0 ? '+' : ''}
|
||
{formatRub(summary.totalPnl)}
|
||
<span style={{ fontSize: 13, fontWeight: 500, marginLeft: 6 }}>
|
||
({formatPct(summary.totalPnlPercent)})
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 4 }}>
|
||
Доходность (weighted)
|
||
</div>
|
||
<div style={{ fontSize: 18, fontWeight: 700, color: pnlColor }}>
|
||
{formatPct(summary.weightedYield)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|