import type { Portfolio } from "../api/usePortfolio"; type Money = Portfolio["totalsByCurrency"][number]; 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}` : ""}`; } function formatMoney(money: Money | null): string { if (!money) return "—"; return `${formatDecimal(money.value)} ${money.currency === "RUB" ? "₽" : money.currency}`; } function formatShare( numerator: Money | null, denominator: Money | null, ): string | null { if (!numerator || !denominator) return null; const total = Number(denominator.value); if (!Number.isFinite(total) || total <= 0) return null; const percent = (Number(numerator.value) / total) * 100; if (!Number.isFinite(percent)) return null; const rounded = new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 1, }).format(percent); return `${rounded} %`; } function formatSnapshotTime(value: string): string { return new Intl.DateTimeFormat("ru-RU", { dateStyle: "medium", timeStyle: "short", timeZone: "UTC", }).format(new Date(value)); } function portfolioErrorCode(error: unknown): string | undefined { return typeof error === "object" && error !== null && "code" in error ? String(error.code) : undefined; } const logoSize = 160; function instrumentLogoUrl(logoName: string | null | undefined): string | null { const stem = logoName?.trim().replace(/\.png$/i, ""); return stem ? `https://invest-brands.cdn-tinkoff.ru/${stem}x${logoSize}.png` : null; } export { formatMoney, formatShare, formatSnapshotTime, instrumentLogoUrl, portfolioErrorCode, };