feat(sf-legacy): expose EGRN + utilities в Обзор tab

Бэкенд /api/v1/parcels/{cad}/analyze возвращает много новых B5 fields
(egrn, utilities, gate_verdict, nspd_zouit_overlaps, ...), но старая Обзор
вкладка показывает только subset (district, score, POI). User просит чтобы
legacy показывал не только старые данные, ближе к Maxim-style макету.

Добавил 2 conditional блока в OverviewTab после District:
- EGRN compact: address / ВРИ / категория / статус / право (если есть)
- Сети рядом: substation/pipeline/water/...  с distances + охранная зона
  ЛЭП warning

Type-only: ParcelAnalysis в types/site-finder.ts расширен полями
egrn (8 optional fields) + utilities (summary array + охранная зона flag).
Поля nullable optional — graceful empty state per cad.

Не трогает новый SF (/site-finder/*) и не меняет существующие блоки
Обзора (district / score / POI / isochrones).
This commit is contained in:
lekss361 2026-05-18 07:21:53 +03:00
parent f6ea27c4f5
commit 6350e3f59a
2 changed files with 115 additions and 0 deletions

View file

@ -103,6 +103,100 @@ export function OverviewTab({ data, onIsochronesResult }: Props) {
</div>
)}
{/* B5 EGRN compact (added 2026-05-18 — expose new field в legacy Обзор) */}
{data.egrn && (
<div
style={{
background: "#fff",
border: "1px solid #e5e7eb",
borderRadius: 10,
padding: "14px 18px",
display: "flex",
flexDirection: "column",
gap: 6,
}}
>
<SectionLabel>ЕГРН</SectionLabel>
<div style={{ fontSize: 13, color: "#374151" }}>
{data.egrn.address && (
<div>
Адрес: <strong>{data.egrn.address}</strong>
</div>
)}
{data.egrn.permitted_use_text && (
<div>
ВРИ: <strong>{data.egrn.permitted_use_text}</strong>
</div>
)}
{data.egrn.land_category && (
<div>
Категория: <strong>{data.egrn.land_category}</strong>
</div>
)}
{data.egrn.parcel_status && (
<div>
Статус: <strong>{data.egrn.parcel_status}</strong>
</div>
)}
{data.egrn.right_type && (
<div>
Право: <strong>{data.egrn.right_type}</strong>
</div>
)}
</div>
</div>
)}
{/* B5 Utilities summary (added 2026-05-18 — expose new field в legacy Обзор) */}
{data.utilities &&
Array.isArray(data.utilities.summary) &&
data.utilities.summary.length > 0 && (
<div
style={{
background: "#fff",
border: "1px solid #e5e7eb",
borderRadius: 10,
padding: "14px 18px",
display: "flex",
flexDirection: "column",
gap: 6,
}}
>
<SectionLabel>Сети рядом</SectionLabel>
<div style={{ fontSize: 13, color: "#374151" }}>
{data.utilities.summary
.map((u) => {
const label =
u.subtype === "substation"
? "электричество"
: u.subtype === "power_line"
? "ЛЭП"
: u.subtype === "pipeline"
? "газ"
: u.subtype === "water_intake"
? "вода"
: u.subtype === "pumping_station"
? "канализация"
: u.subtype;
return `${label} ${u.nearest_m} м`;
})
.join(" · ")}
</div>
{data.utilities.power_line_охранная_зона_flag && (
<div
style={{
fontSize: 12,
color: "#b3261e",
fontWeight: 600,
marginTop: 4,
}}
>
Охранная зона ЛЭП капитальное строительство запрещено
</div>
)}
</div>
)}
{/* Tram warning */}
{nearestTram !== null && (
<div

View file

@ -401,6 +401,27 @@ export interface ParcelAnalysis {
nspd_opportunity_parcels?: import("./nspd").OpportunityParcel[];
nspd_red_lines?: import("./nspd").RedLine[];
nspd_dump?: import("./nspd").NspdDumpMeta | null;
// B5 extended (added 2026-05-18 — expose в legacy Обзор)
egrn?: {
address?: string | null;
permitted_use_text?: string | null;
land_category?: string | null;
parcel_status?: string | null;
right_type?: string | null;
cadastral_value_rub?: number | null;
cost_per_m2_rub?: number | null;
last_egrn_update_date?: string | null;
} | null;
utilities?: {
summary?: Array<{
subtype: string;
nearest_m: number;
name?: string | null;
count_within_2km?: number;
}>;
power_line_охранная_зона_flag?: boolean;
note?: string | null;
} | null;
}
export type PoiCategory =