146 lines
3.7 KiB
TypeScript
146 lines
3.7 KiB
TypeScript
import type { BrokerageOperation } from "@/entities/broker-operation";
|
|
import type {
|
|
BrokerageEvent,
|
|
BrokerageEventsPreviewState,
|
|
} from "@/entities/brokerage-event";
|
|
import type { IncomeSummary } from "@/entities/income";
|
|
import type { InvestmentResourceMeta } from "@/shared/api";
|
|
|
|
const RECENT_EVENTS_LIMIT = 5;
|
|
|
|
type AccountPageIncomeSummary
|
|
= | {
|
|
state: "empty"
|
|
| "loading"
|
|
| "partial";
|
|
to: string;
|
|
}
|
|
| { state: "error"; to: string }
|
|
| {
|
|
state: "loaded";
|
|
summary: IncomeSummary;
|
|
to: string;
|
|
}
|
|
;
|
|
|
|
type AccountPageRecentEvents = BrokerageEventsPreviewState;
|
|
|
|
type AccountPageRecentOperations
|
|
= | {
|
|
items: BrokerageOperation[];
|
|
lastSuccessfulAt?: null | string;
|
|
refreshError?: boolean;
|
|
stale?: boolean;
|
|
state: "loaded" | "partial";
|
|
to: string;
|
|
totalVisible?: boolean;
|
|
}
|
|
| {
|
|
state: "empty"
|
|
| "error"
|
|
| "loading";
|
|
to: string;
|
|
};
|
|
|
|
type PreviewResource<T> = {
|
|
data?: T;
|
|
isError: boolean;
|
|
meta?: Pick<InvestmentResourceMeta,
|
|
"availability"
|
|
| "completeness"
|
|
| "freshness"
|
|
| "lastAttempt"
|
|
| "lastSuccessfulAt"
|
|
>;
|
|
};
|
|
|
|
function toIncomeSummary(
|
|
accountId: string | undefined,
|
|
income: PreviewResource<IncomeSummary>,
|
|
): AccountPageIncomeSummary {
|
|
const to = `/accounts/${accountId}/income`;
|
|
if (!income.data && !income.isError && income.meta?.lastAttempt.state !== "failed")
|
|
return { state: "loading", to };
|
|
if (income.meta?.completeness === "incomplete") return { state: "partial", to };
|
|
if (!income.data && (income.isError || income.meta?.lastAttempt.state === "failed"))
|
|
return { state: "error", to };
|
|
if (!income.data?.totalsByCurrency.length) return { state: "empty", to };
|
|
|
|
return {
|
|
state: "loaded",
|
|
summary: income.data,
|
|
to,
|
|
};
|
|
}
|
|
|
|
function toRecentEvents(
|
|
accountId: string | undefined,
|
|
events: PreviewResource<{ events: BrokerageEvent[] }>,
|
|
): AccountPageRecentEvents {
|
|
const to = `/accounts/${accountId}/events`;
|
|
if (!events.data && !events.isError && events.meta?.lastAttempt.state !== "failed")
|
|
return { state: "loading", to };
|
|
if (events.meta?.completeness === "incomplete")
|
|
return {
|
|
items: events.data?.events.slice(0, RECENT_EVENTS_LIMIT) ?? [],
|
|
state: "partial",
|
|
to,
|
|
totalVisible: false,
|
|
};
|
|
if (!events.data && (events.isError || events.meta?.lastAttempt.state === "failed"))
|
|
return { state: "error", to };
|
|
const items = events.data?.events.slice(0, RECENT_EVENTS_LIMIT) ?? [];
|
|
if (items.length === 0) return { state: "empty", to };
|
|
|
|
return {
|
|
items,
|
|
state: "loaded",
|
|
to,
|
|
totalVisible: events.meta?.completeness === "complete",
|
|
};
|
|
}
|
|
|
|
function toRecentOperations(
|
|
accountId: string | undefined,
|
|
operations: PreviewResource<{ items: BrokerageOperation[] }>,
|
|
): AccountPageRecentOperations {
|
|
const to = `/accounts/${accountId}/operations`;
|
|
if (
|
|
!operations.data
|
|
&& !operations.isError
|
|
&& operations.meta?.lastAttempt.state !== "failed"
|
|
)
|
|
return { state: "loading", to };
|
|
if (operations.meta?.completeness === "incomplete")
|
|
return {
|
|
items: operations.data?.items ?? [],
|
|
state: "partial",
|
|
to,
|
|
totalVisible: false,
|
|
};
|
|
if (
|
|
!operations.data
|
|
&& (operations.isError || operations.meta?.lastAttempt.state === "failed")
|
|
)
|
|
return { state: "error", to };
|
|
if (!operations.data?.items.length) return { state: "empty", to };
|
|
|
|
return {
|
|
items: operations.data.items,
|
|
lastSuccessfulAt: operations.meta?.lastSuccessfulAt,
|
|
refreshError:
|
|
operations.isError || operations.meta?.lastAttempt.state === "failed",
|
|
stale: operations.meta?.freshness === "stale",
|
|
state: "loaded",
|
|
to,
|
|
totalVisible: operations.meta?.completeness === "complete",
|
|
};
|
|
}
|
|
|
|
export { toIncomeSummary, toRecentEvents, toRecentOperations };
|
|
export type {
|
|
AccountPageIncomeSummary,
|
|
AccountPageRecentEvents,
|
|
AccountPageRecentOperations,
|
|
};
|