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.
61 lines
1.5 KiB
TypeScript
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 };
|