"use client"; import { useEffect, useState } from "react"; import { X, Loader2, Sparkles, FileDown, Download, ClipboardCopy } from "lucide-react"; import { Button } from "@/shared/components/ui/button"; import type { ClickedFeature, FeatureDetail, FeatureEnrichmentData } from "../types"; type CfStatus = { available: boolean; expired?: boolean; downloadUrl?: string; documentName?: string }; type FeatureInfoPanelProps = { feature: ClickedFeature | null; onClose: () => void; }; export function FeatureInfoPanel({ feature, onClose }: FeatureInfoPanelProps) { const [detail, setDetail] = useState(null); const [loading, setLoading] = useState(false); const [enriching, setEnriching] = useState(false); const [enrichMsg, setEnrichMsg] = useState(""); const [cfStatus, setCfStatus] = useState(null); // Fetch feature detail useEffect(() => { if (!feature) { setDetail(null); setCfStatus(null); return; } const objectId = feature.properties.object_id ?? feature.properties.objectId; const siruta = feature.properties.siruta; if (!objectId || !siruta) { setDetail(null); return; } let cancelled = false; setLoading(true); setEnrichMsg(""); setCfStatus(null); fetch(`/api/geoportal/feature?objectId=${objectId}&siruta=${siruta}&sourceLayer=${feature.sourceLayer}`) .then((r) => r.ok ? r.json() : Promise.reject()) .then((data: { feature: FeatureDetail }) => { if (cancelled) return; setDetail(data.feature); // Check CF status if we have a cadastral ref const e = data.feature.enrichment as FeatureEnrichmentData | null; const nrCad = e?.NR_CAD ?? data.feature.cadastralRef; if (nrCad) { fetch(`/api/geoportal/cf-status?nrCad=${encodeURIComponent(nrCad)}`) .then((r) => r.ok ? r.json() : null) .then((cf: CfStatus | null) => { if (!cancelled && cf) setCfStatus(cf); }) .catch(() => {}); } }) .catch(() => { if (!cancelled) setDetail(null); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [feature]); if (!feature) return null; const e = detail?.enrichment as FeatureEnrichmentData | null | undefined; const isUat = feature.sourceLayer?.includes("uat"); const cadRef = e?.NR_CAD ?? String(feature.properties.cadastral_ref ?? ""); const title = isUat ? String(feature.properties.name ?? "UAT") : cadRef ? `Parcela ${cadRef}` : `#${feature.properties.object_id ?? "?"}`; const hasEnrichment = !!e && !!e.NR_CAD; const siruta = String(feature.properties.siruta ?? detail?.siruta ?? ""); const handleEnrich = async () => { if (!detail?.id && !siruta) return; setEnriching(true); setEnrichMsg(""); try { const objectId = feature.properties.object_id ?? feature.properties.objectId; const resp = await fetch("/api/geoportal/enrich", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(detail?.id ? { featureId: detail.id } : { siruta, objectId: Number(objectId) }), }); const d = await resp.json(); if (resp.ok) { // Update detail with enrichment data directly from response if (d.enrichment && detail) { setDetail({ ...detail, enrichment: d.enrichment, enrichedAt: new Date().toISOString() }); } else { // Fallback: reload from API const oid = feature.properties.object_id ?? feature.properties.objectId; if (oid) { const r = await fetch(`/api/geoportal/feature?objectId=${oid}&siruta=${siruta}&sourceLayer=${feature.sourceLayer}`); if (r.ok) { const data = await r.json(); setDetail(data.feature); } } } setEnrichMsg(""); } else { setEnrichMsg(d.error ?? "Eroare la enrichment"); } } catch { setEnrichMsg("Eroare retea"); } finally { setEnriching(false); } }; const handleCopy = () => { const text = [ cadRef && `Nr. cad: ${cadRef}`, e?.NR_CF && `CF: ${e.NR_CF}`, (e?.SUPRAFATA_2D ?? feature.properties.area_value) && `S: ${e?.SUPRAFATA_2D ?? feature.properties.area_value} mp`, e?.PROPRIETARI && e.PROPRIETARI !== "-" && `Prop: ${e.PROPRIETARI}`, siruta && `SIRUTA: ${siruta}`, ].filter(Boolean).join("\n"); navigator.clipboard.writeText(text); }; return (
{/* Header */}

{title}

{loading && (
Se incarca...
)} {!loading && isUat && ( <> )} {!loading && !isUat && ( <> {hasEnrichment && ( <> {e?.PROPRIETARI && e.PROPRIETARI !== "-" && } {e?.INTRAVILAN && e.INTRAVILAN !== "-" && } {e?.CATEGORIE_FOLOSINTA && e.CATEGORIE_FOLOSINTA !== "-" && } )} {/* Action buttons */}
{!hasEnrichment && ( )} {cfStatus?.available && cfStatus.downloadUrl ? ( ) : cadRef ? ( ) : null}
{enrichMsg && (

{enrichMsg}

)} )}
); } function Row({ label, value }: { label: string; value: unknown }) { if (!value || value === "-" || value === "") return null; return (
{label} {String(value)}
); } function formatArea(v: unknown): string { if (!v || v === "") return ""; const n = typeof v === "number" ? v : parseFloat(String(v)); if (isNaN(n)) return String(v); return `${n.toLocaleString("ro-RO")} mp`; }