"use client";
import { useState } from "react";
import type { NeighborsSummary } from "@/types/site-finder";
interface Props {
data: NeighborsSummary;
}
function fmtPrice(n: number | null | undefined): string {
if (n == null) return "—";
if (n >= 1000) {
return `${(n / 1000).toFixed(0)} тыс ₽/м²`;
}
return `${n.toLocaleString("ru-RU")} ₽/м²`;
}
function fmtYearBuilt(y: number | null | undefined): string {
if (y == null || y === 0) return "—";
return String(y);
}
// Русский plural: 1 → "здание", 2-4 → "здания", 5+ → "зданий".
// Также корректно для 11-14 (zданий), 21 (здание), 22 (здания) etc.
function pluralBuildings(n: number): string {
const mod10 = n % 10;
const mod100 = n % 100;
if (mod100 >= 11 && mod100 <= 14) return "зданий";
if (mod10 === 1) return "здание";
if (mod10 >= 2 && mod10 <= 4) return "здания";
return "зданий";
}
export function NeighborsBlock({ data }: Props) {
const [expanded, setExpanded] = useState(false);
if (!data.data_available) {
return (
Соседи (100 м)
{data.note ?? "Данные о соседних зданиях недоступны"}
);
}
const count = data.count_buildings_100m ?? 0;
const hasOverlap = !!data.has_existing_buildings;
return (
Соседи (100 м)
{count} {pluralBuildings(count)}
{/* Overlap warning — hard warn */}
{hasOverlap &&
data.overlap_buildings &&
data.overlap_buildings.length > 0 && (
На участке уже есть здания (overlap >50 м²)
{data.overlap_buildings.map((b) => (
-
{b.building_name ?? b.readable_address ?? b.cad_num}
{b.floors ? `, ${b.floors} эт.` : ""}
{b.overlap_m2 ? ` — пересечение ~${b.overlap_m2} м²` : ""}
))}
Инвестиции невозможны без сноса.
)}
{/* Summary metrics */}
{count > 0 && (
Средн. этажность
{data.avg_floors_100m ?? "—"}
Макс. этажей
{data.max_floors_100m ?? "—"}
Медиана цены
{fmtPrice(data.median_cost_per_m2_100m)}
)}
{/* Toggle neighbor list */}
{data.neighbors && data.neighbors.length > 0 && (
{expanded && (
|
Здание
|
Эт.
|
Год
|
₽/м²
|
Дист.
|
{data.neighbors.map((n) => (
|
{n.building_name ?? n.readable_address ?? n.cad_num}
|
{n.floors ?? "—"}
|
{fmtYearBuilt(n.year_built)}
|
{fmtPrice(n.cost_per_m2)}
|
{n.distance_m} м
|
))}
)}
)}
{data.note && (
{data.note}
)}
);
}