feat: add portfolio
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { formatDecimal, formatMoney } from "./display";
|
||||
|
||||
describe("portfolio display helpers", () => {
|
||||
it("formats decimal strings without financial arithmetic", () => {
|
||||
expect(formatDecimal("-1234567.89")).toBe("-1 234 567,89");
|
||||
expect(formatMoney({ value: "10", currency: "RUB" })).toBe("10 ₽");
|
||||
expect(formatMoney({ value: "0.5", currency: "USD" })).toBe("0,5 USD");
|
||||
expect(formatMoney(null)).toBe("—");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { Portfolio } from "../api/usePortfolio";
|
||||
|
||||
type Money = Portfolio["totalsByCurrency"][number];
|
||||
|
||||
export function formatDecimal(value: string): string {
|
||||
const [integer, fraction] = value.split(".");
|
||||
const sign = integer.startsWith("-") ? "-" : "";
|
||||
const grouped = (sign ? integer.slice(1) : integer).replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
" ",
|
||||
);
|
||||
return `${sign}${grouped}${fraction ? `,${fraction}` : ""}`;
|
||||
}
|
||||
|
||||
export function formatMoney(money: Money | null): string {
|
||||
if (!money) return "—";
|
||||
return `${formatDecimal(money.value)} ${money.currency === "RUB" ? "₽" : money.currency}`;
|
||||
}
|
||||
|
||||
export function formatSnapshotTime(value: string): string {
|
||||
return new Intl.DateTimeFormat("ru-RU", {
|
||||
dateStyle: "medium",
|
||||
timeStyle: "short",
|
||||
timeZone: "UTC",
|
||||
}).format(new Date(value));
|
||||
}
|
||||
|
||||
export function portfolioErrorCode(error: unknown): string | undefined {
|
||||
return typeof error === "object" && error !== null && "code" in error
|
||||
? String(error.code)
|
||||
: undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user