diff --git a/frontend/src/components/site-finder/analysis/Section2NetworksUtilities.tsx b/frontend/src/components/site-finder/analysis/Section2NetworksUtilities.tsx index 9d5193e5..77209674 100644 --- a/frontend/src/components/site-finder/analysis/Section2NetworksUtilities.tsx +++ b/frontend/src/components/site-finder/analysis/Section2NetworksUtilities.tsx @@ -14,6 +14,7 @@ */ import type { ReactNode } from "react"; +import dynamic from "next/dynamic"; import { Zap, Flame, @@ -21,11 +22,53 @@ import { Pipette, AlertTriangle, Info, + MapPin, } from "lucide-react"; +import type { Geometry } from "geojson"; import { HeadlineBar } from "@/components/ui/HeadlineBar"; import { NspdVerifyLink } from "./NspdVerifyLink"; import { useParcelAnalyzeQuery } from "@/lib/site-finder-api"; -import type { UtilitySummaryItem } from "@/lib/site-finder-api"; +import type { + ParcelAnalyzeResponse, + UtilitySummaryItem, +} from "@/lib/site-finder-api"; +import type { ParcelAnalysis } from "@/types/site-finder"; +import { useConnectionPoints } from "@/hooks/useConnectionPoints"; + +// ── Connection-points map (#1746) ───────────────────────────────────────────── +// Высота тайла карты для drill-in уровня раздела. Легенда + CpLayerControlPanel +// рендерятся flow-потоком ПОД картой внутри SiteMap, поэтому обёртка НЕ задаёт +// height/overflow (иначе клипнёт контролы — см. урок MiniMap.tsx #1218). +const CP_MAP_HEIGHT = 340; + +// Leaflet использует window → монтируем только на клиенте (ssr:false), как в +// MiniMap.tsx. НЕ импортировать SiteMap в server component. +const SiteMap = dynamic( + () => + import("@/components/site-finder/SiteMap").then((m) => ({ + default: m.SiteMap, + })), + { + ssr: false, + loading: () => ( +
+ Загрузка карты... +
+ ), + }, +); // ── Subtype display config ──────────────────────────────────────────────────── @@ -525,6 +568,135 @@ function UtilitiesTable({ items }: UtilitiesTableProps) { ); } +// ── Connection-points map block (#1746) ─────────────────────────────────────── + +/** + * Адаптирует /analyze-ответ в минимальный ParcelAnalysis, который SiteMap + * требует обязательным prop `data`. Для контекста карты точек подключения нужен + * только геом участка (geom_geojson) + cad_num + source — остальные required- + * поля заполняем безопасными дефолтами (без рыночных слоёв: тут показываем + * только точки подключения + охранные зоны сетей). Зеркалит toSiteMapData из + * MiniMap.tsx, но без проброса competitors/pipeline/opportunity (не нужны). + */ +function toCpMapData(data: ParcelAnalyzeResponse): ParcelAnalysis { + return { + cad_num: data.cad_num, + source: data.source === "cad_building" ? "cad_building" : "cad_quarter", + geom_geojson: (data.geom_geojson as Geometry) ?? null, + score: data.score, + score_breakdown: {}, + poi_count: 0, + competitors: [], + noise: null, + air_quality: null, + wind: null, + district: data.district ?? null, + // #255 — ЗОУИТ overlaps (охранные зоны сетей) для слоя ZouitLayer. + nspd_zouit_overlaps: data.nspd_zouit_overlaps ?? undefined, + }; +} + +interface ConnectionPointsMapProps { + data: ParcelAnalyzeResponse; +} + +function ConnectionPointsMap({ data }: ConnectionPointsMapProps) { + // Точки подключения ресурсов (электро/газ/вода/тепло) по кварталу — тянем по + // cad_num и пробрасываем в SiteMap, который рисует ConnectionPointsLayer + + // CpLayerControlPanel при truthy prop `connectionPoints` (паттерн MiniMap.tsx). + const { data: connectionPoints, isLoading } = useConnectionPoints( + data.cad_num, + ); + + const hasPoints = + !!connectionPoints && + connectionPoints.dump_available && + connectionPoints.engineering_structures.length > 0; + + return ( +
+ {/* Label над картой */} +
+ +

+ Точки подключения и охранные зоны сетей (НСПД) +

+
+

+ Инженерные объекты и зоны с особыми условиями из снимка кадастрового + квартала (НСПД). Показывает, где находятся точки подключения, а не только + расстояние до них. +

+ + {isLoading ? ( +
+ Загрузка точек подключения... +
+ ) : hasPoints ? ( + + ) : ( +
+ + Точки подключения по кварталу не загружены. Снимок инженерной + инфраструктуры НСПД для этого кадастрового квартала отсутствует. +
+ )} +
+ ); +} + // ── Main component ──────────────────────────────────────────────────────────── interface Props { @@ -640,6 +812,9 @@ export function Section2NetworksUtilities({ cad }: Props) { {/* Utilities table */} + {/* Карта точек подключения + охранных зон сетей (#1746) */} + + {/* Caveat note */} {note && (