"use client"; import { useState, useCallback } from "react"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/shared/components/ui/card"; import { Button } from "@/shared/components/ui/button"; import { Input } from "@/shared/components/ui/input"; import { Label } from "@/shared/components/ui/label"; import { Badge } from "@/shared/components/ui/badge"; import { Switch } from "@/shared/components/ui/switch"; import { Loader2, ChevronDown, ChevronUp, Download, Search, FileText, AlertCircle } from "lucide-react"; import { cn } from "@/shared/lib/utils"; /* ------------------------------------------------------------------ */ /* Types — loosely typed since eTerra response shape varies */ /* ------------------------------------------------------------------ */ type Application = Record; type IssuedDoc = Record; /* ------------------------------------------------------------------ */ /* Helpers */ /* ------------------------------------------------------------------ */ /** Safely read a nested string field from a record. */ function str(obj: Record, ...keys: string[]): string { for (const k of keys) { const v = obj[k]; if (typeof v === "string" && v.length > 0) return v; if (typeof v === "number") return String(v); } return ""; } /** Parse a date string (various eTerra formats) into a Date, or null. */ function parseDate(raw: unknown): Date | null { if (!raw) return null; if (typeof raw === "number") return new Date(raw); if (typeof raw === "string") { const d = new Date(raw); if (!isNaN(d.getTime())) return d; } return null; } /** Format a date for display (DD.MM.YYYY). */ function fmtDate(raw: unknown): string { const d = parseDate(raw); if (!d) return "-"; const dd = String(d.getDate()).padStart(2, "0"); const mm = String(d.getMonth() + 1).padStart(2, "0"); const yyyy = d.getFullYear(); return `${dd}.${mm}.${yyyy}`; } /** Check if a date value is in the future. */ function isFuture(raw: unknown): boolean { const d = parseDate(raw); if (!d) return false; return d.getTime() > Date.now(); } /** Detect if an application looks "solutionat" (solved). */ function isSolutionat(app: Application): boolean { const status = String( app.statusName ?? app.status ?? app.statusCode ?? app.applicationStatus ?? "" ).toLowerCase(); return ( status.includes("solu") || status.includes("rezolv") || status.includes("finalizat") || status.includes("closed") || status.includes("eliberat") ); } /** Get the due date from an application (tries common field names). */ function getDueDate(app: Application): unknown { return ( app.dueDate ?? app.solutionDeadline ?? app.termenSolutionare ?? app.deadline ?? app.termenLegal ?? null ); } /* ------------------------------------------------------------------ */ /* Sub-components */ /* ------------------------------------------------------------------ */ function StatusBadge({ app }: { app: Application }) { const raw = String( app.statusName ?? app.status ?? app.statusCode ?? app.applicationStatus ?? "Necunoscut" ); const lower = raw.toLowerCase(); let variant: "default" | "secondary" | "destructive" | "outline" = "outline"; if (lower.includes("solu") || lower.includes("finalizat") || lower.includes("eliberat")) { variant = "default"; } else if (lower.includes("suspenda") || lower.includes("reject")) { variant = "destructive"; } else if (lower.includes("lucr") || lower.includes("analiz")) { variant = "secondary"; } return {raw}; } function IssuedDocsPanel({ applicationId, workspaceId, }: { applicationId: string; workspaceId: number; }) { const [docs, setDocs] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [loaded, setLoaded] = useState(false); const loadDocs = useCallback(async () => { if (loaded) return; setLoading(true); setError(null); try { const res = await fetch( `/api/eterra/rgi/issued-docs?applicationId=${encodeURIComponent(applicationId)}&workspaceId=${workspaceId}` ); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error( (body as Record).error ? String((body as Record).error) : `HTTP ${res.status}` ); } const data: unknown = await res.json(); // eTerra can return { elements: [...] } or just an array let list: IssuedDoc[] = []; if (Array.isArray(data)) { list = data as IssuedDoc[]; } else if (data && typeof data === "object" && Array.isArray((data as Record).elements)) { list = (data as Record).elements as IssuedDoc[]; } else if (data && typeof data === "object" && Array.isArray((data as Record).content)) { list = (data as Record).content as IssuedDoc[]; } setDocs(list); setLoaded(true); } catch (err) { setError(err instanceof Error ? err.message : "Eroare la incarcarea documentelor"); } finally { setLoading(false); } }, [applicationId, workspaceId, loaded]); // Auto-load on mount if (!loaded && !loading && !error) { loadDocs(); } if (loading) { return (
Se incarca documentele eliberate...
); } if (error) { return (
{error}
); } if (!docs || docs.length === 0) { return (
Niciun document eliberat gasit.
); } return (

Documente eliberate ({docs.length})

{docs.map((doc, i) => { const docId = str(doc, "issuedDocumentId", "documentId", "id", "pk"); const docNr = str(doc, "documentNumber", "number", "nr", "nrDocument") || docId; const docType = str(doc, "documentTypeName", "documentType", "type", "tipDocument"); const docDate = doc.documentDate ?? doc.date ?? doc.dataDocument ?? doc.issueDate; const docStatus = str(doc, "statusName", "status", "documentStatus"); return ( ); })}
Nr. document Tip Data Status Actiuni
{docNr || "-"} {docType || "-"} {fmtDate(docDate)} {docStatus || "-"} {docId ? ( Descarca ) : ( N/A )}
{/* Raw JSON for debugging */}
Raspuns brut JSON
          {JSON.stringify(docs, null, 2)}
        
); } /* ------------------------------------------------------------------ */ /* ApplicationRow */ /* ------------------------------------------------------------------ */ function ApplicationRow({ app, workspaceId, }: { app: Application; workspaceId: number; }) { const [expanded, setExpanded] = useState(false); const appId = str(app, "applicationId", "id", "pk", "applicationPk"); const appNr = str(app, "applicationNumber", "number", "nrCerere", "registrationNumber") || appId; const serviceType = str(app, "serviceTypeName", "serviceType", "tipServiciu", "serviceName"); const applicant = str(app, "applicantName", "applicant", "deponent", "ownerName", "solicitant"); const submitDate = app.submitDate ?? app.registrationDate ?? app.dataCerere ?? app.dataInregistrare; const dueDate = getDueDate(app); return ( <> {appNr || "-"} {serviceType || "-"} {applicant || "-"} {fmtDate(submitDate)} {fmtDate(dueDate)} {expanded && (
{/* Application raw details */}
Date aplicatie (JSON brut)
                  {JSON.stringify(app, null, 2)}
                
)} ); } /* ------------------------------------------------------------------ */ /* Main Page */ /* ------------------------------------------------------------------ */ export default function RgiTestPage() { // Filter state const [workspaceId, setWorkspaceId] = useState(127); const [orgUnitId, setOrgUnitId] = useState(127002); const [year, setYear] = useState("2026"); const [onlyFutureSolved, setOnlyFutureSolved] = useState(false); // Data state const [applications, setApplications] = useState([]); const [totalCount, setTotalCount] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const loadApplications = useCallback(async () => { setLoading(true); setError(null); try { const res = await fetch("/api/eterra/rgi/applications", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ workspaceId, orgUnitId, year, page: 0, nrElements: 100, }), }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error( (body as Record).error ? String((body as Record).error) : `HTTP ${res.status}` ); } const data: unknown = await res.json(); // Extract the list from various possible response shapes let list: Application[] = []; let total: number | null = null; if (Array.isArray(data)) { list = data as Application[]; total = list.length; } else if (data && typeof data === "object") { const obj = data as Record; if (Array.isArray(obj.elements)) { list = obj.elements as Application[]; } else if (Array.isArray(obj.content)) { list = obj.content as Application[]; } else if (Array.isArray(obj.data)) { list = obj.data as Application[]; } if (typeof obj.totalElements === "number") total = obj.totalElements; else if (typeof obj.total === "number") total = obj.total; else if (typeof obj.totalCount === "number") total = obj.totalCount; else total = list.length; } setApplications(list); setTotalCount(total); } catch (err) { setError(err instanceof Error ? err.message : "Eroare la incarcarea lucrarilor"); setApplications([]); setTotalCount(null); } finally { setLoading(false); } }, [workspaceId, orgUnitId, year]); // Apply client-side filter const displayedApps = onlyFutureSolved ? applications.filter((app) => isSolutionat(app) && isFuture(getDueDate(app))) : applications; return (
{/* Header */}

Documente Eliberate eTerra

Pagina de test — lucrari depuse cu documente eliberate

{/* Filters */} Filtre Selecteaza judetul, unitatea administrativ-teritoriala si anul
setWorkspaceId(Number(e.target.value))} className="w-32" placeholder="127" />

127 = Cluj

setOrgUnitId(Number(e.target.value))} className="w-32" placeholder="127002" />
setYear(e.target.value)} className="w-24" placeholder="2026" />
{/* Future/solved filter toggle */}
{onlyFutureSolved && applications.length > 0 && ( {displayedApps.length} / {applications.length} )}
{/* Error */} {error && (

Eroare

{error}

)} {/* Results */} {!loading && applications.length > 0 && ( Lucrari {displayedApps.length} {totalCount !== null && totalCount !== displayedApps.length ? ` / ${totalCount} total` : ""}
{displayedApps.map((app, i) => { const key = str(app, "applicationId", "id", "pk") || String(i); return ( ); })}
Nr. cerere Tip serviciu Deponent Data depunere Termen Status Actiuni
{displayedApps.length === 0 && (
Nicio lucrare nu corespunde filtrelor selectate.
)}
)} {/* Empty state */} {!loading && !error && applications.length === 0 && totalCount === null && (

Apasa "Incarca lucrari" pentru a interoga eTerra RGI.

Asigura-te ca sesiunea eTerra este activa (conecteaza-te din ParcelSync).

)} {/* Loading state for initial load */} {loading && (

Se interogheaza eTerra RGI...

Poate dura cateva secunde.

)} {/* Raw response debug */} {applications.length > 0 && (
Raspuns brut — toate aplicatiile ({applications.length})
            {JSON.stringify(applications.slice(0, 5), null, 2)}
            {applications.length > 5 && `\n\n... si inca ${applications.length - 5} aplicatii`}
          
)}
); }