diff --git a/src/modules/parcel-sync/components/parcel-sync-module.tsx b/src/modules/parcel-sync/components/parcel-sync-module.tsx index 71293da..fa11cf7 100644 --- a/src/modules/parcel-sync/components/parcel-sync-module.tsx +++ b/src/modules/parcel-sync/components/parcel-sync-module.tsx @@ -390,6 +390,11 @@ export function ParcelSyncModule() { totalImmovables: number; withGeometry: number; noGeomCount: number; + localDbTotal: number; + localDbWithGeom: number; + localDbNoGeom: number; + localDbEnriched: number; + localSyncFresh: boolean; } | null>(null); const [noGeomScanSiruta, setNoGeomScanSiruta] = useState(""); // siruta for which scan was done @@ -686,6 +691,16 @@ export function ParcelSyncModule() { setNoGeomScanning(true); setNoGeomScan(null); setNoGeomScanSiruta(s); + const emptyResult = { + totalImmovables: 0, + withGeometry: 0, + noGeomCount: 0, + localDbTotal: 0, + localDbWithGeom: 0, + localDbNoGeom: 0, + localDbEnriched: 0, + localSyncFresh: false, + }; try { const res = await fetch("/api/eterra/no-geom-scan", { method: "POST", @@ -695,25 +710,24 @@ export function ParcelSyncModule() { workspacePk: workspacePk ?? undefined, }), }); - const data = (await res.json()) as { - totalImmovables?: number; - withGeometry?: number; - noGeomCount?: number; - error?: string; - }; + const data = (await res.json()) as Record; if (data.error) { console.warn("[no-geom-scan]", data.error); - setNoGeomScan({ totalImmovables: 0, withGeometry: 0, noGeomCount: 0 }); + setNoGeomScan(emptyResult); } else { setNoGeomScan({ - totalImmovables: data.totalImmovables ?? 0, - withGeometry: data.withGeometry ?? 0, - noGeomCount: data.noGeomCount ?? 0, + totalImmovables: Number(data.totalImmovables ?? 0), + withGeometry: Number(data.withGeometry ?? 0), + noGeomCount: Number(data.noGeomCount ?? 0), + localDbTotal: Number(data.localDbTotal ?? 0), + localDbWithGeom: Number(data.localDbWithGeom ?? 0), + localDbNoGeom: Number(data.localDbNoGeom ?? 0), + localDbEnriched: Number(data.localDbEnriched ?? 0), + localSyncFresh: Boolean(data.localSyncFresh), }); } } catch { - // Show zero result on network error - setNoGeomScan({ totalImmovables: 0, withGeometry: 0, noGeomCount: 0 }); + setNoGeomScan(emptyResult); } setNoGeomScanning(false); }, @@ -2385,6 +2399,112 @@ export function ParcelSyncModule() { ); + // Helper: local DB status line + const localDbLine = scanDone && noGeomScan.localDbTotal > 0 && ( +
+ + + Baza de date locală:{" "} + + {noGeomScan.localDbWithGeom.toLocaleString("ro-RO")} + {" "} + cu geometrie + {noGeomScan.localDbNoGeom > 0 && ( + <> + {" + "} + + {noGeomScan.localDbNoGeom.toLocaleString("ro-RO")} + {" "} + fără geometrie + + )} + {noGeomScan.localDbEnriched > 0 && ( + <> + {" · "} + + {noGeomScan.localDbEnriched.toLocaleString("ro-RO")} + {" "} + îmbogățite + + )} + {noGeomScan.localSyncFresh && ( + + (proaspăt) + + )} + +
+ ); + + // Helper: workflow preview (what Magic will do) + const workflowPreview = scanDone && ( +
+

+ La apăsarea Magic, pașii vor fi: +

+
    +
  1. + {noGeomScan.localSyncFresh && noGeomScan.localDbWithGeom > 0 + ? "Sync terenuri + clădiri — " + : "Sync terenuri + clădiri — "} + 0 + ? "text-emerald-600 dark:text-emerald-400" + : "text-foreground", + )} + > + {noGeomScan.localSyncFresh && + noGeomScan.localDbWithGeom > 0 + ? "skip (date proaspete în DB)" + : `descarcă ${noGeomScan.withGeometry.toLocaleString("ro-RO")} features`} + +
  2. + {includeNoGeom && ( +
  3. + Import parcele fără geometrie —{" "} + + {(() => { + const newNoGeom = Math.max( + 0, + noGeomScan.noGeomCount - noGeomScan.localDbNoGeom, + ); + return newNoGeom > 0 + ? `~${newNoGeom.toLocaleString("ro-RO")} noi de importat` + : "deja importate"; + })()} + +
  4. + )} +
  5. + Îmbogățire CF, proprietari, adrese —{" "} + + {(() => { + const totalToEnrich = + noGeomScan.localDbTotal + + (includeNoGeom + ? Math.max( + 0, + noGeomScan.noGeomCount - + noGeomScan.localDbNoGeom, + ) + : 0); + const remaining = + totalToEnrich - noGeomScan.localDbEnriched; + return remaining > 0 + ? `~${remaining.toLocaleString("ro-RO")} de procesat (~${Math.ceil((remaining * 0.25) / 60)} min)` + : "deja îmbogățite"; + })()} + +
  6. +
  7. Generare GPKG + CSV
  8. +
  9. Comprimare ZIP + descărcare
  10. +
+
+ ); + // No-geometry parcels found if (hasNoGeomParcels) return ( @@ -2419,6 +2539,7 @@ export function ParcelSyncModule() { Cele fără geometrie există în baza de date eTerra dar nu au contur desenat în layerul GIS.

+ {localDbLine}