feat: show persisted investment data and sync state

Consume the provided resource-envelope API snapshot. Preserve financial snapshots during
refresh, observe synchronization without importing, and fence late responses across
account and connection changes.
This commit is contained in:
2026-09-26 21:22:49 +03:00
parent b987fd8e78
commit 4e5f564fa1
81 changed files with 4714 additions and 1420 deletions
@@ -2,7 +2,7 @@ import { Card, Group, SimpleGrid, Stack, Text } from "@mantine/core";
import type { FC } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router";
import { formatDate, formatMoney } from "@/shared/lib";
import { formatDate, formatMoney, formatSnapshotTime } from "@/shared/lib";
import type { BrokerageAccountCard } from "../../model/display";
import { accountTypeKey } from "../../model/display";
import classes from "./BrokerageAccountList.module.css";
@@ -52,8 +52,8 @@ const BrokerageAccountList: FC<BrokerageAccountListProps> = (props) => {
const { t } = useTranslation();
return (
<SimpleGrid className={classes.list} cols={{ base: 1, lg: 2 }} spacing="lg">
{accounts.map(({ account, summary, positionCounts }) => (
<SimpleGrid className={classes.list} cols={1} spacing="lg">
{accounts.map(({ account, summary, positionCounts, source }) => (
<Card
component={Link}
to={`/accounts/${account.id}`}
@@ -92,6 +92,25 @@ const BrokerageAccountList: FC<BrokerageAccountListProps> = (props) => {
{t("accounts.currentValue")}
</Text>
<BrokerageAccountSummary summary={summary} />
{source?.lastSuccessfulAt ? (
<Text size="xs" c="dimmed">
{t("investment.sourceTime", {
date: formatSnapshotTime(source.lastSuccessfulAt),
})}
</Text>
) : null}
{source?.sync.state === "running" ||
source?.sync.state === "queued" ? (
<Text size="xs" role="status">
{t("accounts.refreshing")}
</Text>
) : null}
{source?.sync.state === "failed" ? (
<Text size="xs">{t("accounts.refreshError")}</Text>
) : null}
{source?.freshness === "stale" ? (
<Text size="xs">{t("investment.stale")}</Text>
) : null}
</Stack>
{positionCounts ? (
<dl className={classes.positions}>