"use client"; import { useEffect, useState } from "react"; import type { NspdDumpMeta, NspdZoning } from "@/types/nspd"; interface Props { data: NspdZoning | null | undefined; dump: NspdDumpMeta | null | undefined; cadNum: string; } export function NspdZoningBlock({ data, dump, cadNum }: Props) { const [expanded, setExpanded] = useState(false); const isHarvesting = dump?.harvest_triggered && !dump?.available; const eta = dump?.harvest_eta_seconds ?? null; // Issue #234: countdown пока harvest идёт. const [remaining, setRemaining] = useState(eta); useEffect(() => { setRemaining(eta); }, [eta]); useEffect(() => { if (!isHarvesting) return; if (remaining === null || remaining <= 0) return; const id = setInterval(() => { setRemaining((v) => (v === null || v <= 1 ? 0 : v - 1)); }, 1000); return () => clearInterval(id); }, [isHarvesting, remaining]); // Issue #234: после ETA*1.5 показываем «не дождались», fallthrough к no-data UI. // remaining === 0 значит таймер успел истечь (eta был известен). const harvestTimedOut = isHarvesting && !data && remaining !== null && remaining <= 0; if (harvestTimedOut) { return (
Данные НСПД загружаются дольше обычного. Попробуйте обновить страницу через минуту.
Открыть в ПКК
); } // Loading skeleton when harvest is in progress if (isHarvesting && !data) { const label = remaining !== null && remaining > 0 ? `Загружаем данные НСПД, осталось ~${remaining} с…` : "Загружаем данные НСПД…"; return (
{label}
); } // Data not available, no harvest triggered if (!data) { return (
Данные ПЗЗ из НСПД недоступны. Используйте{" "} Публичную кадастровую карту {" "} для кад. номера {cadNum} .
Открыть в ПКК
); } return (
{data.zone_code && ( {data.zone_code} )} {data.zone_name && ( {data.zone_name} )} {!data.zone_code && !data.zone_name && ( Зона не определена )}
{data.raw_props && Object.keys(data.raw_props).length > 0 && (
{expanded && (
{Object.entries(data.raw_props).map(([k, v]) => (
{k}: {String(v ?? "—")}
))}
)}
)} {dump?.fetched_at_utc && (
НСПД: данные от{" "} {new Date(dump.fetched_at_utc).toLocaleDateString("ru-RU")} {dump.stale && ( (устаревшие) )}
)}
); }