"use client"; import { ArrowUpRight } from "lucide-react"; import dynamic from "next/dynamic"; import Link from "next/link"; import { useParams } from "next/navigation"; import { KpiCard } from "@/components/analytics/KpiCard"; import { LazyMount } from "@/components/analytics/LazyMount"; import { ObjectChecksBadges } from "@/components/analytics/ObjectChecksBadges"; import { ObjectDocumentsList } from "@/components/analytics/ObjectDocumentsList"; import { ObjectMetroList } from "@/components/analytics/ObjectMetroList"; import { ObjectQuartirographyTable } from "@/components/analytics/ObjectQuartirographyTable"; import { ObjectSpecsTable } from "@/components/analytics/ObjectSpecsTable"; import { Section } from "@/components/analytics/Section"; import { useObjectBuildings, useObjectChecks, useObjectDocuments, useObjectFullDetail, useObjectQuartirography, useObjectSalesAgg, } from "@/lib/analytics-api"; // Heavy sections deferred so initial paint and main-thread are not blocked. const ObjectSaleChart = dynamic( () => import("@/components/analytics/ObjectSaleChart").then( (m) => m.ObjectSaleChart, ), { ssr: false, loading: () => (
), }, ); const ObjectInfraMap = dynamic( () => import("@/components/analytics/ObjectInfraMap").then( (m) => m.ObjectInfraMap, ), { ssr: false, loading: () => ( ), }, ); const ObjectPhotoGallery = dynamic( () => import("@/components/analytics/ObjectPhotoGallery").then( (m) => m.ObjectPhotoGallery, ), { ssr: false, loading: () => , }, ); export default function ObjectDrillInPage() { const params = useParams<{ id: string }>(); const objId = params.id; const fullDetail = useObjectFullDetail(objId); const agg = useObjectSalesAgg(objId); const buildings = useObjectBuildings(objId); const quartirography = useObjectQuartirography(objId); const checks = useObjectChecks(objId); const documents = useObjectDocuments(objId); const apartments = agg.data?.find((r) => r.type === "apartments"); const parking = agg.data?.find((r) => r.type === "parking"); const nonliv = agg.data?.find((r) => r.type === "nonliv"); const d = fullDetail.data; // Cross-link target (#65): first building's cadastral number — a real parcel // Site Finder can analyze. Объект сам по себе не несёт cad_quarter, но корпуса // из NSPD несут cad_num, что и есть точка входа в анализ участка. const siteFinderCad = buildings.data?.find( (b) => b.cad_num != null && b.cad_num !== "", )?.cad_num; return ( <> ← К PRINZIP{d?.addr ?? ""} · obj_id={d?.obj_id} · {d?.dev_name ?? ""} {d?.escrow ? " · эскроу" : ""}
{/* ── KPI row — распроданность ────────────────────────────────────────── */}| {h} | ))}|||||
|---|---|---|---|---|---|
| {b.cad_num ?? "—"} | {b.floors ?? "—"} | {b.area != null ? b.area.toLocaleString("ru-RU", { maximumFractionDigits: 1, }) : "—"} | {b.purpose ?? "—"} | {b.building_name ?? "—"} | {b.readable_address ?? "—"} |
Геометрия корпусов ещё не подгружена с NSPD.