Files
frontend/src/pages/accounts/ui/AccountsPage/components/AccountsRefreshState.view.tsx
T
ksv741 4e5f564fa1 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.
2026-09-26 21:22:49 +03:00

61 lines
1.5 KiB
TypeScript

import { Alert, Button, Group, Loader, Stack, Text } from "@mantine/core";
import type { FC } from "react";
import { useTranslation } from "react-i18next";
import { formatSnapshotTime } from "@/shared/lib";
type AccountsRefreshStateProps = {
lastSuccessfulAt?: string | null;
sourceError?: boolean;
refreshing?: boolean;
refreshError?: boolean;
retry?: () => void;
};
const AccountsRefreshState: FC<AccountsRefreshStateProps> = (props) => {
const { refreshing = false, refreshError = false, retry } = props;
const { t } = useTranslation();
return (
<>
{props.lastSuccessfulAt ? (
<Text size="xs" c="dimmed">
{t("investment.sourceTime", {
date: formatSnapshotTime(props.lastSuccessfulAt),
})}
</Text>
) : null}
<Button
onClick={retry}
disabled={refreshing}
variant="light"
w="fit-content"
>
{t(refreshError ? "accounts.retry" : "investment.refresh")}
</Button>
{refreshing ? (
<Group gap="xs" role="status" aria-label={t("accounts.refreshing")}>
<Loader size="sm" />
<Text c="dimmed" size="sm">
{t("accounts.refreshing")}
</Text>
</Group>
) : null}
{refreshError ? (
<Alert color="orange" role="status" aria-live="polite">
<Stack gap="sm">
<Text>
{t(
props.sourceError
? "investment.syncFailed"
: "accounts.refreshError",
)}
</Text>
</Stack>
</Alert>
) : null}
</>
);
};
export { AccountsRefreshState, type AccountsRefreshStateProps };