feat: show return, cash and structure on account cards (#114)
Frontend verify / commits (pull_request) Successful in 29s
Frontend verify / security (pull_request) Successful in 8s
Frontend verify / verify (pull_request) Failing after 4m34s

This commit is contained in:
2026-10-27 05:03:12 +03:00
parent b037fd9cab
commit c3c1528fd4
12 changed files with 984 additions and 431 deletions
+12
View File
@@ -42,6 +42,18 @@ describe("shared display helpers", () => {
formatMoney({ currency: "RUB", value: "1.5" }, { withZeroCents: true }),
).toBe("1,50 ₽");
expect(formatMoney(null)).toBe("—");
expect(formatMoney(
{ currency: "RUB", value: "136900" },
{ withSign: true },
)).toBe("+136 900 ₽");
expect(formatMoney(
{ currency: "RUB", value: "-4200" },
{ withSign: true },
)).toBe("−4 200 ₽");
expect(formatMoney(
{ currency: "RUB", value: "-0.00" },
{ withSign: true },
)).toBe("0,00 ₽");
});
it("builds the brand logo url from an upstream file name", () => {
+32 -2
View File
@@ -3,9 +3,17 @@ const CENTS_PRECISION = 2;
type FormatMoneyOptions = {
withRoundedCents?: boolean;
withSign?: boolean;
withZeroCents?: boolean;
};
const portfolioCategoryPresentation = {
BOND: { color: "grape.6", label: "portfolio.bonds" },
CASH: { color: "green.6", label: "portfolio.structure.cash" },
OTHER: { color: "orange.6", label: "portfolio.structure.other" },
STOCK: { color: "blue.6", label: "portfolio.stocks" },
} as const;
type Money = { currency: string; value: string };
const dateFormatter = new Intl.DateTimeFormat("ru-RU", {
@@ -40,7 +48,11 @@ function formatMoney(
money: Money
| null
| undefined,
{ withRoundedCents = false, withZeroCents = false }: FormatMoneyOptions = {},
{
withRoundedCents = false,
withSign = false,
withZeroCents = false,
}: FormatMoneyOptions = {},
): string {
if (!money) return "—";
@@ -62,8 +74,25 @@ function formatMoney(
: integerPart;
const currency = money.currency === "RUB" ? "₽" : money.currency;
const formatted = `${formatDecimal(decimal)} ${currency}`;
return `${formatDecimal(decimal)} ${currency}`;
if (!withSign) return formatted;
if (isZeroDecimal(value))
return value.startsWith("-") ? formatted.slice(1) : formatted;
return value.startsWith("-") ? `−${formatted.slice(1)}` : `+${formatted}`;
}
function isZeroDecimal(value: string) {
const unsigned = value.startsWith("-") ? value.slice(1) : value;
const [integer = "", fraction = ""] = unsigned.split(
".",
DECIMAL_PART_COUNT,
);
return integer.replaceAll("0", "") === ""
&& fraction.replaceAll("0", "") === "";
}
function roundDecimalToCents(value: string): string {
@@ -116,4 +145,5 @@ export {
formatMoney,
formatSnapshotTime,
instrumentLogoUrl,
portfolioCategoryPresentation,
};
+1
View File
@@ -7,6 +7,7 @@ export {
formatMoney,
formatSnapshotTime,
instrumentLogoUrl,
portfolioCategoryPresentation,
} from "./display";
export { useInitialAvailability } from "./initial-availability";
export { useUrlPeriod } from "./useUrlPeriod";