import type { ObjectFullDetail } from "@/types/analytics"; interface SpecRow { label: string; value: string | null; } function yn(v: boolean | null | undefined): string | null { if (v === null || v === undefined) return null; return v ? "Да" : "Нет"; } function num(v: number | null | undefined, suffix = ""): string | null { if (v === null || v === undefined) return null; return `${v.toLocaleString("ru-RU")}${suffix}`; } function numFmt( v: number | null | undefined, decimals = 0, suffix = "", ): string | null { if (v === null || v === undefined) return null; return ( v.toLocaleString("ru-RU", { minimumFractionDigits: decimals, maximumFractionDigits: decimals, }) + suffix ); } function price(v: number | null | undefined): string | null { if (v === null || v === undefined) return null; return ( (v / 1_000_000).toLocaleString("ru-RU", { minimumFractionDigits: 1, maximumFractionDigits: 1, }) + " млн ₽" ); } function priceM2(v: number | null | undefined): string | null { if (v === null || v === undefined) return null; return v.toLocaleString("ru-RU", { maximumFractionDigits: 0 }) + " ₽/м²"; } export function ObjectSpecsTable({ d }: { d: ObjectFullDetail }) { const specs: SpecRow[] = [ // Identity { label: "Класс объекта", value: d.obj_class }, { label: "Класс энергоэффективности", value: d.energy_eff }, { label: "Материал стен", value: d.wall_type }, { label: "Первый этаж", value: d.first_floor_type }, // Building { label: "Подъездов", value: num(d.section_count) }, { label: "Этажей (max)", value: num(d.floor_max) }, { label: "Высота потолков", value: numFmt(d.ceiling_height_m, 2, " м") }, { label: "Лифты пассажирские", value: d.elevators_passenger_count === 0 ? "Нет" : num(d.elevators_passenger_count), }, { label: "Лифты грузовые", value: d.elevators_cargo_count === 0 ? "Нет" : num(d.elevators_cargo_count), }, // Parking { label: "Машино-мест (парковка)", value: num(d.parking_total_slots), }, { label: "Гостевые (приказ.)", value: num(d.guest_parking_inside_count), }, { label: "Гостевые (улица)", value: num(d.guest_parking_outside_count), }, { label: "Обеспеченность парковкой", value: numFmt(d.parking_provision_pct, 1, "%"), }, // Apartments { label: "Квартир всего", value: num(d.flat_count) }, { label: "Площадь квартир", value: d.flat_area_min != null && d.flat_area_max != null ? `${numFmt(d.flat_area_min, 1)} – ${numFmt(d.flat_area_max, 1)} м²` : null, }, { label: "Средняя площадь квартиры", value: numFmt(d.avg_flat_area_m2, 1, " м²"), }, { label: "Вариантов отделки", value: num(d.finishing_variants_count), }, { label: "Свободная планировка", value: yn(d.has_free_planning) }, // Price { label: "Цена (от)", value: price(d.price_min_rub), }, { label: "Цена (до)", value: price(d.price_max_rub), }, { label: "Цена/м² (от)", value: priceM2(d.price_per_m2_min), }, { label: "Цена/м² (до)", value: priceM2(d.price_per_m2_max), }, // Yard { label: "Детских площадок", value: num(d.playground_kids_count), }, { label: "Спортивных площадок", value: num(d.playground_sport_count), }, { label: "Велодорожки", value: yn(d.has_bike_paths) }, { label: "Мусорные площадки", value: num(d.trash_areas_count), }, // OVZ { label: "Пандус", value: yn(d.has_ramp) }, { label: "Понижающие платформы (ОВЗ)", value: yn(d.has_low_platforms) }, { label: "Инвалидный подъёмник", value: yn(d.has_wheelchair_lift), }, // Developer { label: "Девелопер", value: d.dev_name }, { label: "Группа компаний", value: d.dev_group_name }, { label: "Эскроу", value: yn(d.escrow) }, { label: "Декларация №", value: d.project_declaration_num, }, { label: "Дата публикации проекта", value: d.project_published_at?.slice(0, 10) ?? null, }, ]; const filtered = specs.filter((s) => s.value !== null); if (filtered.length === 0) { return (

Характеристики ещё не загружены.

); } return (
{filtered.map((s) => ( ))}
{s.label} {s.value}
); }