diff --git a/src/app/api/eterra/sync-background/route.ts b/src/app/api/eterra/sync-background/route.ts
index 8940377..f340ee1 100644
--- a/src/app/api/eterra/sync-background/route.ts
+++ b/src/app/api/eterra/sync-background/route.ts
@@ -221,6 +221,21 @@ async function runBackground(params: {
throw new Error(r.error ?? "Sync clădiri failed");
}
+ // Sync intravilan limits (always, lightweight layer)
+ phase = "Sincronizare limite intravilan";
+ push({});
+ try {
+ await syncLayer(username, password, siruta, "LIMITE_INTRAV_DYNAMIC", {
+ forceFullSync: forceSync,
+ jobId,
+ isSubStep: true,
+ });
+ } catch {
+ // Non-critical — don't fail the whole job
+ note = "Avertisment: limite intravilan nu s-au sincronizat";
+ push({});
+ }
+
if (!terenuriNeedsSync && !cladiriNeedsSync) {
note = "Date proaspete — sync skip";
}
diff --git a/src/modules/parcel-sync/components/epay-tab.tsx b/src/modules/parcel-sync/components/epay-tab.tsx
index adf52f5..03450b2 100644
--- a/src/modules/parcel-sync/components/epay-tab.tsx
+++ b/src/modules/parcel-sync/components/epay-tab.tsx
@@ -60,7 +60,7 @@ type GisUatResult = {
/* ------------------------------------------------------------------ */
function formatDate(iso?: string | null) {
- if (!iso) return "\u2014";
+ if (!iso) return "—";
return new Date(iso).toLocaleDateString("ro-RO", {
day: "2-digit",
month: "2-digit",
@@ -71,7 +71,7 @@ function formatDate(iso?: string | null) {
}
function formatShortDate(iso?: string | null) {
- if (!iso) return "\u2014";
+ if (!iso) return "—";
return new Date(iso).toLocaleDateString("ro-RO", {
day: "2-digit",
month: "2-digit",
@@ -715,7 +715,7 @@ export function EpayTab() {
{formatShortDate(order.expiresAt)}
) : (
- {"\u2014"}
+ {"—"}
)}
diff --git a/src/modules/parcel-sync/components/parcel-sync-module.tsx b/src/modules/parcel-sync/components/parcel-sync-module.tsx
index d9ca7d3..61a56e3 100644
--- a/src/modules/parcel-sync/components/parcel-sync-module.tsx
+++ b/src/modules/parcel-sync/components/parcel-sync-module.tsx
@@ -445,7 +445,13 @@ export function ParcelSyncModule() {
-
+ s + c, 0)}
+ onSyncRefresh={() => void fetchSyncStatus()}
+ />
);
diff --git a/src/modules/parcel-sync/components/tabs/export-tab.tsx b/src/modules/parcel-sync/components/tabs/export-tab.tsx
index 186baec..4e9fc69 100644
--- a/src/modules/parcel-sync/components/tabs/export-tab.tsx
+++ b/src/modules/parcel-sync/components/tabs/export-tab.tsx
@@ -1189,7 +1189,7 @@ export function ExportTab({
Sync fundal — Bază
- Terenuri + clădiri \u2192 salvează în DB
+ Terenuri + clădiri → salvează în DB
@@ -1215,7 +1215,7 @@ export function ExportTab({
Sync fundal — Magic
- Sync + îmbogățire \u2192 salvează în DB
+ Sync + îmbogățire → salvează în DB
@@ -1311,7 +1311,7 @@ export function ExportTab({
{bgPhaseTrail.map((p, i) => (
- {i > 0 && \u2192}
+ {i > 0 && →}
{phaseTrail.map((p, i) => (
- {i > 0 && \u2192}
+ {i > 0 && →}
-
- QGIS \u2192 Layer \u2192 Add Layer \u2192 Add PostGIS Layers
+ QGIS → Layer → Add Layer → Add PostGIS Layers
- New connection:
diff --git a/src/modules/parcel-sync/components/tabs/map-tab.tsx b/src/modules/parcel-sync/components/tabs/map-tab.tsx
index 7da0b88..4d6025b 100644
--- a/src/modules/parcel-sync/components/tabs/map-tab.tsx
+++ b/src/modules/parcel-sync/components/tabs/map-tab.tsx
@@ -2,7 +2,8 @@
import { useState, useRef, useCallback, useEffect } from "react";
import dynamic from "next/dynamic";
-import { Map as MapIcon, Loader2, AlertTriangle } from "lucide-react";
+import { Map as MapIcon, Loader2, AlertTriangle, RefreshCw } from "lucide-react";
+import { Button } from "@/shared/components/ui/button";
import { Card, CardContent } from "@/shared/components/ui/card";
import { Badge } from "@/shared/components/ui/badge";
import { BasemapSwitcher } from "@/modules/geoportal/components/basemap-switcher";
@@ -54,6 +55,9 @@ const BASE_LAYERS = [
type MapTabProps = {
siruta: string;
sirutaValid: boolean;
+ sessionConnected: boolean;
+ syncLocalCount: number; // total local features for this UAT
+ onSyncRefresh: () => void;
};
/* ------------------------------------------------------------------ */
@@ -84,7 +88,7 @@ function asMap(handle: MapViewerHandle | null): MapLike | null {
/* Component */
/* ------------------------------------------------------------------ */
-export function MapTab({ siruta, sirutaValid }: MapTabProps) {
+export function MapTab({ siruta, sirutaValid, sessionConnected, syncLocalCount, onSyncRefresh }: MapTabProps) {
const mapHandleRef = useRef(null);
const [basemap, setBasemap] = useState("liberty");
const [clickedFeature, setClickedFeature] =
@@ -104,6 +108,10 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
edge: number;
} | null>(null);
+ /* Quick sync state */
+ const [syncing, setSyncing] = useState(false);
+ const [syncMsg, setSyncMsg] = useState("");
+
/* Layer visibility: show terenuri + cladiri, hide admin */
const [layerVisibility] = useState({
terenuri: true,
@@ -419,6 +427,30 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
setSelectionMode(mode);
}, []);
+ /* ── Quick sync (terenuri + cladiri + intravilan) ──────────── */
+ const handleQuickSync = useCallback(async () => {
+ if (!siruta || syncing || !sessionConnected) return;
+ setSyncing(true);
+ setSyncMsg("Se sincronizează...");
+ try {
+ const res = await fetch("/api/eterra/sync-background", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ siruta, mode: "base" }),
+ });
+ const data = (await res.json()) as { jobId?: string; error?: string };
+ if (data.error) {
+ setSyncMsg(`Eroare: ${data.error}`);
+ } else {
+ setSyncMsg("Sincronizare pornită în fundal. Revino în câteva minute.");
+ onSyncRefresh();
+ }
+ } catch {
+ setSyncMsg("Eroare rețea");
+ }
+ setSyncing(false);
+ }, [siruta, syncing, sessionConnected, onSyncRefresh]);
+
/* ── Render ─────────────────────────────────────────────────── */
if (!sirutaValid) {
@@ -432,6 +464,43 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
);
}
+ /* No data for this UAT — show sync button */
+ if (syncLocalCount === 0) {
+ return (
+
+
+
+
+ Nu există date locale pentru acest UAT.
+
+ {sessionConnected ? (
+
+
+ {syncMsg && (
+
{syncMsg}
+ )}
+
+ ) : (
+
+ Conectează-te la eTerra pentru a sincroniza date.
+
+ )}
+
+
+ );
+ }
+
return (
{/* Boundary mismatch alert */}