feat: add broker investment performance
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@family-budget/frontend",
|
||||
"version": "0.14.0",
|
||||
"version": "0.15.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ImportBrokerReportResponse, ImportPortfolioResponse, PortfolioFile, PortfolioHistoryResponse, PortfolioOverviewResponse } from '@family-budget/shared';
|
||||
import type { ImportBrokerReportResponse, ImportPortfolioResponse, PortfolioFile, PortfolioHistoryResponse, PortfolioOverviewResponse, PortfolioPerformanceResponse } from '@family-budget/shared';
|
||||
import { api } from './client';
|
||||
|
||||
export function importPortfolio(data: PortfolioFile): Promise<ImportPortfolioResponse> {
|
||||
@@ -18,3 +18,7 @@ export function getPortfolioOverview(): Promise<PortfolioOverviewResponse> {
|
||||
export function getPortfolioHistory(): Promise<PortfolioHistoryResponse> {
|
||||
return api.get('/api/portfolio/history');
|
||||
}
|
||||
|
||||
export function getPortfolioPerformance(): Promise<PortfolioPerformanceResponse> {
|
||||
return api.get('/api/portfolio/performance');
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||
import type { PortfolioHistoryResponse, PortfolioOverviewResponse } from '@family-budget/shared';
|
||||
import { getPortfolioHistory, getPortfolioOverview } from '../api/portfolio';
|
||||
import type { PortfolioHistoryResponse, PortfolioOverviewResponse, PortfolioPerformanceResponse } from '@family-budget/shared';
|
||||
import { getPortfolioHistory, getPortfolioOverview, getPortfolioPerformance } from '../api/portfolio';
|
||||
import { formatDate } from '../utils/format';
|
||||
|
||||
const money = new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB', minimumFractionDigits: 2 });
|
||||
@@ -10,10 +10,12 @@ const number = new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 6 });
|
||||
export function PortfolioPage() {
|
||||
const [data, setData] = useState<PortfolioOverviewResponse | null>(null);
|
||||
const [history, setHistory] = useState<PortfolioHistoryResponse | null>(null);
|
||||
const [performance, setPerformance] = useState<PortfolioPerformanceResponse | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
getPortfolioOverview().then(setData).catch(() => {});
|
||||
getPortfolioHistory().then(setHistory).catch(() => {});
|
||||
getPortfolioPerformance().then(setPerformance).catch(() => {});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -75,6 +77,20 @@ export function PortfolioPage() {
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
|
||||
{performance?.accounts.map((account) => (
|
||||
<section className="portfolio" key={`performance-${account.accountId}`} aria-labelledby={`performance-${account.accountId}`}>
|
||||
<h2 id={`performance-${account.accountId}`} className="portfolio__title">Результат · {account.accountName}</h2>
|
||||
<div className="summary portfolio__performance">
|
||||
<div className="summary__card summary__card--investments"><div className="summary__label">Пополнения</div><div className="summary__value">{money.format(account.contributions / 100)}</div></div>
|
||||
<div className="summary__card summary__card--investments"><div className="summary__label">Выводы</div><div className="summary__value">{money.format(account.withdrawals / 100)}</div></div>
|
||||
<div className="summary__card summary__card--income"><div className="summary__label">Купоны и дивиденды</div><div className="summary__value">{money.format(account.income / 100)}</div></div>
|
||||
<div className="summary__card summary__card--expense"><div className="summary__label">Комиссии</div><div className="summary__value">{money.format(account.fees / 100)}</div></div>
|
||||
<div className="summary__card summary__card--positive"><div className="summary__label">Результат продаж</div><div className="summary__value">{money.format(account.realizedResult / 100)}</div></div>
|
||||
{account.unrealizedResult !== null && <div className="summary__card summary__card--positive"><div className="summary__label">Нереализованный результат</div><div className="summary__value">{money.format(account.unrealizedResult / 100)}</div></div>}
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user