gendesign/tradein-mvp/frontend/src/components/trade-in/saleShareUtils.ts
lekss361 f8112b420d
Some checks failed
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been cancelled
feat(tradein): страница «доля квартир дома в продаже» — % слайдер, адреса, карта (#2058)
2026-06-28 14:53:38 +00:00

68 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Утилиты страницы sale-share: цвет/размер тепловых маркеров + форматтеры.
/**
* Цвет «тепла» доли в продаже: низкая (норма) → зелёный, высокая (сигнал
* расселения / инвест-выхода / проблемного дома) → красный. null → серый.
* Пороги согласованы с корзинами гистограммы (HISTOGRAM_BUCKETS на бэкенде).
*/
export function heatColor(pct: number | null): string {
if (pct === null) return "#9ca3af"; // gray-400 — знаменатель неизвестен
if (pct < 5) return "#16a34a"; // green-600
if (pct < 10) return "#65a30d"; // lime-600
if (pct < 20) return "#ca8a04"; // yellow-600
if (pct < 30) return "#ea580c"; // orange-600
if (pct < 50) return "#dc2626"; // red-600
if (pct <= 100) return "#b91c1c"; // red-700
return "#7f1d1d"; // red-900 — over_100
}
/** Радиус маркера на карте: 5..14 px, растёт с долей. null → минимум. */
export function markerRadius(pct: number | null): number {
if (pct === null) return 5;
const clamped = Math.min(Math.max(pct, 0), 100);
return 5 + (clamped / 100) * 9;
}
export function fmtRub(v: number | null | undefined): string {
return v === null || v === undefined ? "—" : v.toLocaleString("ru-RU");
}
export function fmtPct(v: number | null | undefined): string {
if (v === null || v === undefined) return "—";
return v >= 100 ? `${Math.round(v)}%` : `${v.toFixed(1)}%`;
}
export function fmtDays(v: number | null | undefined): string {
return v === null || v === undefined ? "—" : `${Math.round(v)} дн`;
}
const HOUSE_TYPE_LABELS: Record<string, string> = {
panel: "Панель",
brick: "Кирпич",
monolith: "Монолит",
monolith_brick: "Монолит-кирпич",
block: "Блочный",
wood: "Дерево",
stalin: "Сталинка",
other: "Другое",
};
/** Гуманизация типа дома; неизвестное значение отдаём как есть. */
export function houseTypeLabel(t: string | null | undefined): string {
if (!t) return "—";
return HOUSE_TYPE_LABELS[t] ?? t;
}
const SOURCE_LABELS: Record<string, string> = {
cian: "Циан",
avito: "Avito",
yandex: "Я.Недв",
domklik: "ДомКлик",
rosreestr: "Росреестр",
n1: "N1.ru",
};
export function sourceLabel(s: string | null | undefined): string {
if (!s) return "—";
return SOURCE_LABELS[s] ?? s;
}