feat: add account metadata and interest analytics
This commit is contained in:
@@ -7,6 +7,8 @@ export function AccountsList() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [editingId, setEditingId] = useState<number | null>(null);
|
||||
const [editAlias, setEditAlias] = useState('');
|
||||
const [editAccountType, setEditAccountType] = useState<Account['accountType']>(null);
|
||||
const [editStatus, setEditStatus] = useState<Account['status']>('active');
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
@@ -19,12 +21,16 @@ export function AccountsList() {
|
||||
const handleEdit = (account: Account) => {
|
||||
setEditingId(account.id);
|
||||
setEditAlias(account.alias || '');
|
||||
setEditAccountType(account.accountType);
|
||||
setEditStatus(account.status);
|
||||
};
|
||||
|
||||
const handleSave = async (id: number) => {
|
||||
try {
|
||||
const updated = await updateAccount(id, {
|
||||
alias: editAlias.trim(),
|
||||
accountType: editAccountType,
|
||||
status: editStatus,
|
||||
});
|
||||
setAccounts((prev) =>
|
||||
prev.map((a) => (a.id === id ? updated : a)),
|
||||
@@ -48,6 +54,8 @@ export function AccountsList() {
|
||||
<th className="data-table__head-cell">Номер счёта</th>
|
||||
<th className="data-table__head-cell">Валюта</th>
|
||||
<th className="data-table__head-cell">Алиас</th>
|
||||
<th className="data-table__head-cell">Тип</th>
|
||||
<th className="data-table__head-cell">Статус</th>
|
||||
<th className="data-table__head-cell"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -76,6 +84,25 @@ export function AccountsList() {
|
||||
)
|
||||
)}
|
||||
</td>
|
||||
<td className="data-table__cell">
|
||||
{editingId === a.id ? (
|
||||
<select value={editAccountType ?? ''} onChange={(e) => setEditAccountType((e.target.value || null) as Account['accountType'])}>
|
||||
<option value="">Не указан</option>
|
||||
<option value="brokerage">Брокерский</option>
|
||||
<option value="iis">ИИС</option>
|
||||
<option value="savings">Накопительный</option>
|
||||
<option value="current">Текущий</option>
|
||||
</select>
|
||||
) : (({ brokerage: 'Брокерский', iis: 'ИИС', savings: 'Накопительный', current: 'Текущий' } as Record<string, string>)[a.accountType ?? ''] || 'не указан')}
|
||||
</td>
|
||||
<td className="data-table__cell">
|
||||
{editingId === a.id ? (
|
||||
<select value={editStatus} onChange={(e) => setEditStatus(e.target.value as Account['status'])}>
|
||||
<option value="active">Действующий</option>
|
||||
<option value="closed">Закрытый</option>
|
||||
</select>
|
||||
) : (a.status === 'closed' ? 'Закрытый' : 'Действующий')}
|
||||
</td>
|
||||
<td className="data-table__cell">
|
||||
{editingId === a.id ? (
|
||||
<div className="button-group">
|
||||
@@ -105,7 +132,7 @@ export function AccountsList() {
|
||||
))}
|
||||
{accounts.length === 0 && (
|
||||
<tr className="data-table__row">
|
||||
<td colSpan={5} className="data-table__cell data-table__cell--center text text--muted">
|
||||
<td colSpan={7} className="data-table__cell data-table__cell--center text text--muted">
|
||||
Нет счетов. Импортируйте выписку.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -40,6 +40,7 @@ export function SummaryCards({ summary }: Props) {
|
||||
</div>
|
||||
<div className="summary__subvalue">Поступило: {formatAmount(summary.cashInflow)}</div>
|
||||
<div className="summary__subvalue">Списано: {formatAmount(summary.cashOutflow)}</div>
|
||||
<div className="summary__subvalue">Доход от процентов: {formatAmount(summary.interestIncome)}</div>
|
||||
{(summary.transferInflow > 0 || summary.transferOutflow > 0) && (
|
||||
<div className="summary__subvalue">
|
||||
Переводы: {formatAmount(summary.transferInflow)} / {formatAmount(summary.transferOutflow)}
|
||||
|
||||
Reference in New Issue
Block a user