fix(parcel-sync): replace Unicode escapes with actual Romanian diacritics
The \u0103, \u00ee etc. escape sequences were rendering literally in JSX text nodes instead of displaying ă, î, ț, ș characters. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -77,11 +77,11 @@ export function ConnectionPill({
|
|||||||
)}
|
)}
|
||||||
<span className="hidden sm:inline">
|
<span className="hidden sm:inline">
|
||||||
{connecting
|
{connecting
|
||||||
? "Se conecteaz\u0103\u2026"
|
? "Se conectează…"
|
||||||
: session.connected
|
: session.connected
|
||||||
? "eTerra"
|
? "eTerra"
|
||||||
: session.eterraMaintenance
|
: session.eterraMaintenance
|
||||||
? "Mentenan\u021b\u0103"
|
? "Mentenanță"
|
||||||
: connectionError
|
: connectionError
|
||||||
? "Eroare"
|
? "Eroare"
|
||||||
: "Deconectat"}
|
: "Deconectat"}
|
||||||
@@ -128,11 +128,11 @@ export function ConnectionPill({
|
|||||||
<AlertTriangle className="h-3.5 w-3.5 text-amber-500 mt-0.5 shrink-0" />
|
<AlertTriangle className="h-3.5 w-3.5 text-amber-500 mt-0.5 shrink-0" />
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium text-amber-700 dark:text-amber-400">
|
<p className="font-medium text-amber-700 dark:text-amber-400">
|
||||||
eTerra este \u00een mentenan\u021b\u0103
|
eTerra este în mentenanță
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-[11px] text-amber-600/80 dark:text-amber-400/70">
|
<p className="mt-1 text-[11px] text-amber-600/80 dark:text-amber-400/70">
|
||||||
Platforma ANCPI nu este disponibil\u0103 momentan. Conectarea va fi
|
Platforma ANCPI nu este disponibilă momentan. Conectarea va fi
|
||||||
reactivat\u0103 automat c\u00e2nd serviciul revine online.
|
reactivată automat când serviciul revine online.
|
||||||
</p>
|
</p>
|
||||||
{session.eterraHealthMessage && (
|
{session.eterraHealthMessage && (
|
||||||
<p className="mt-1 text-[10px] opacity-60 font-mono">
|
<p className="mt-1 text-[10px] opacity-60 font-mono">
|
||||||
@@ -149,9 +149,9 @@ export function ConnectionPill({
|
|||||||
!connectionError &&
|
!connectionError &&
|
||||||
!session.eterraMaintenance && (
|
!session.eterraMaintenance && (
|
||||||
<div className="px-3 py-3 text-xs text-muted-foreground">
|
<div className="px-3 py-3 text-xs text-muted-foreground">
|
||||||
<p>Conexiunea se face automat c\u00e2nd \u00eencepi s\u0103 scrii un UAT.</p>
|
<p>Conexiunea se face automat când începi să scrii un UAT.</p>
|
||||||
<p className="mt-1 text-[11px] opacity-70">
|
<p className="mt-1 text-[11px] opacity-70">
|
||||||
Creden\u021bialele sunt preluate din configurarea serverului.
|
Credențialele sunt preluate din configurarea serverului.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -162,7 +162,7 @@ export function ConnectionPill({
|
|||||||
!session.eterraMaintenance && (
|
!session.eterraMaintenance && (
|
||||||
<div className="px-3 py-3 text-xs text-muted-foreground">
|
<div className="px-3 py-3 text-xs text-muted-foreground">
|
||||||
<p>
|
<p>
|
||||||
Conexiunea automat\u0103 a e\u0219uat. Verific\u0103 creden\u021bialele din
|
Conexiunea automată a eșuat. Verifică credențialele din
|
||||||
variabilele de mediu (ETERRA_USERNAME / ETERRA_PASSWORD).
|
variabilele de mediu (ETERRA_USERNAME / ETERRA_PASSWORD).
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -182,7 +182,7 @@ export function ConnectionPill({
|
|||||||
{session.activeJobPhase && (
|
{session.activeJobPhase && (
|
||||||
<span className="opacity-70">
|
<span className="opacity-70">
|
||||||
{" "}
|
{" "}
|
||||||
\u2014 {session.activeJobPhase}
|
— {session.activeJobPhase}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -194,14 +194,14 @@ export function ParcelSyncModule() {
|
|||||||
...prev,
|
...prev,
|
||||||
eterraMaintenance: true,
|
eterraMaintenance: true,
|
||||||
eterraAvailable: false,
|
eterraAvailable: false,
|
||||||
eterraHealthMessage: data.error ?? "eTerra \u00een mentenan\u021b\u0103",
|
eterraHealthMessage: data.error ?? "eTerra în mentenanță",
|
||||||
}));
|
}));
|
||||||
autoConnectAttempted.current = false;
|
autoConnectAttempted.current = false;
|
||||||
} else {
|
} else {
|
||||||
setConnectionError(data.error ?? "Eroare conectare");
|
setConnectionError(data.error ?? "Eroare conectare");
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setConnectionError("Eroare re\u021bea");
|
setConnectionError("Eroare rețea");
|
||||||
}
|
}
|
||||||
setConnecting(false);
|
setConnecting(false);
|
||||||
}, [session.connected, session.eterraMaintenance, connecting, fetchSession]);
|
}, [session.connected, session.eterraMaintenance, connecting, fetchSession]);
|
||||||
@@ -222,7 +222,7 @@ export function ParcelSyncModule() {
|
|||||||
setConnectionError(data.error ?? "Nu se poate deconecta");
|
setConnectionError(data.error ?? "Nu se poate deconecta");
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setConnectionError("Eroare re\u021bea");
|
setConnectionError("Eroare rețea");
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ export function ParcelSyncModule() {
|
|||||||
<MapPin className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground pointer-events-none" />
|
<MapPin className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground pointer-events-none" />
|
||||||
<Input
|
<Input
|
||||||
id="uat-search"
|
id="uat-search"
|
||||||
placeholder="Selecteaz\u0103 UAT \u2014 scrie nume sau cod SIRUTA\u2026"
|
placeholder="Selectează UAT — scrie nume sau cod SIRUTA…"
|
||||||
value={uatQuery}
|
value={uatQuery}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setUatQuery(e.target.value);
|
setUatQuery(e.target.value);
|
||||||
@@ -329,7 +329,7 @@ export function ParcelSyncModule() {
|
|||||||
<span className="text-muted-foreground">({item.siruta})</span>
|
<span className="text-muted-foreground">({item.siruta})</span>
|
||||||
{item.county && (
|
{item.county && (
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground">
|
||||||
{"\u2013 "}
|
{"– "}
|
||||||
<span className="font-medium text-foreground/70">
|
<span className="font-medium text-foreground/70">
|
||||||
jud. {item.county}
|
jud. {item.county}
|
||||||
</span>
|
</span>
|
||||||
@@ -363,7 +363,7 @@ export function ParcelSyncModule() {
|
|||||||
<TabsList>
|
<TabsList>
|
||||||
<TabsTrigger value="search" className="gap-1.5">
|
<TabsTrigger value="search" className="gap-1.5">
|
||||||
<Search className="h-4 w-4" />
|
<Search className="h-4 w-4" />
|
||||||
C\u0103utare Parcele
|
Căutare Parcele
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="layers" className="gap-1.5">
|
<TabsTrigger value="layers" className="gap-1.5">
|
||||||
<Layers className="h-4 w-4" />
|
<Layers className="h-4 w-4" />
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export const normalizeText = (text: string) =>
|
|||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
export function formatDate(iso?: string | null) {
|
export function formatDate(iso?: string | null) {
|
||||||
if (!iso) return "\u2014";
|
if (!iso) return "—";
|
||||||
return new Date(iso).toLocaleDateString("ro-RO", {
|
return new Date(iso).toLocaleDateString("ro-RO", {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "2-digit",
|
month: "2-digit",
|
||||||
@@ -96,13 +96,13 @@ export function formatDate(iso?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function formatArea(val?: number | null) {
|
export function formatArea(val?: number | null) {
|
||||||
if (val == null) return "\u2014";
|
if (val == null) return "—";
|
||||||
return val.toLocaleString("ro-RO", { maximumFractionDigits: 2 }) + " mp";
|
return val.toLocaleString("ro-RO", { maximumFractionDigits: 2 }) + " mp";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format ISO date as DD.MM.YYYY (no time) */
|
/** Format ISO date as DD.MM.YYYY (no time) */
|
||||||
export function formatShortDate(iso?: string | null) {
|
export function formatShortDate(iso?: string | null) {
|
||||||
if (!iso) return "\u2014";
|
if (!iso) return "—";
|
||||||
const d = new Date(iso);
|
const d = new Date(iso);
|
||||||
const dd = String(d.getDate()).padStart(2, "0");
|
const dd = String(d.getDate()).padStart(2, "0");
|
||||||
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
||||||
@@ -110,7 +110,7 @@ export function formatShortDate(iso?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function relativeTime(date: Date | null) {
|
export function relativeTime(date: Date | null) {
|
||||||
if (!date) return "niciodat\u0103";
|
if (!date) return "niciodată";
|
||||||
const mins = Math.floor((Date.now() - date.getTime()) / 60_000);
|
const mins = Math.floor((Date.now() - date.getTime()) / 60_000);
|
||||||
if (mins < 1) return "acum";
|
if (mins < 1) return "acum";
|
||||||
if (mins < 60) return `acum ${mins} min`;
|
if (mins < 60) return `acum ${mins} min`;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export function DatabaseTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<Loader2 className="h-8 w-8 mx-auto mb-3 animate-spin opacity-40" />
|
<Loader2 className="h-8 w-8 mx-auto mb-3 animate-spin opacity-40" />
|
||||||
<p>Se \u00eencarc\u0103 datele din baza de date\u2026</p>
|
<p>Se încarcă datele din baza de date…</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
@@ -64,9 +64,9 @@ export function DatabaseTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<Database className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<Database className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p className="font-medium">Nicio dat\u0103 \u00een baza de date</p>
|
<p className="font-medium">Nicio dată în baza de date</p>
|
||||||
<p className="text-xs mt-1">
|
<p className="text-xs mt-1">
|
||||||
Folose\u0219te tab-ul Export pentru a sincroniza date din eTerra.
|
Folosește tab-ul Export pentru a sincroniza date din eTerra.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -81,7 +81,7 @@ export function DatabaseTab({
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Database className="h-4 w-4 text-muted-foreground" />
|
<Database className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
{dbSummary.totalFeatures.toLocaleString("ro-RO")} entit\u0103\u021bi
|
{dbSummary.totalFeatures.toLocaleString("ro-RO")} entități
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-muted-foreground">
|
<span className="text-xs text-muted-foreground">
|
||||||
din {dbSummary.totalUats} UAT-uri
|
din {dbSummary.totalUats} UAT-uri
|
||||||
@@ -99,7 +99,7 @@ export function DatabaseTab({
|
|||||||
) : (
|
) : (
|
||||||
<RefreshCw className="h-3 w-3 mr-1" />
|
<RefreshCw className="h-3 w-3 mr-1" />
|
||||||
)}
|
)}
|
||||||
Re\u00eencarc\u0103
|
Reîncarcă
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ export function DatabaseTab({
|
|||||||
Dashboard
|
Dashboard
|
||||||
</Button>
|
</Button>
|
||||||
<span className="text-xs text-muted-foreground">
|
<span className="text-xs text-muted-foreground">
|
||||||
{oldestSync ? relativeTime(oldestSync) : "\u2014"}
|
{oldestSync ? relativeTime(oldestSync) : "—"}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -212,7 +212,7 @@ export function DatabaseTab({
|
|||||||
{noGeomTotal > 0 && (
|
{noGeomTotal > 0 && (
|
||||||
<span className="inline-flex items-center gap-1">
|
<span className="inline-flex items-center gap-1">
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground">
|
||||||
F\u0103r\u0103 geom:
|
Fără geom:
|
||||||
</span>
|
</span>
|
||||||
<span className="font-medium tabular-nums text-amber-600 dark:text-amber-400">
|
<span className="font-medium tabular-nums text-amber-600 dark:text-amber-400">
|
||||||
{noGeomTotal.toLocaleString("ro-RO")}
|
{noGeomTotal.toLocaleString("ro-RO")}
|
||||||
@@ -239,7 +239,7 @@ export function DatabaseTab({
|
|||||||
? "border-teal-200 bg-teal-50/50 dark:border-teal-800 dark:bg-teal-950/30"
|
? "border-teal-200 bg-teal-50/50 dark:border-teal-800 dark:bg-teal-950/30"
|
||||||
: "border-muted bg-muted/30",
|
: "border-muted bg-muted/30",
|
||||||
)}
|
)}
|
||||||
title={`${label}: ${layer.count} entit\u0103\u021bi${isEnriched ? `, ${layer.enrichedCount} \u00eembog\u0103\u021bite` : ""}${layer.lastSynced ? `, sync: ${new Date(layer.lastSynced).toLocaleDateString("ro-RO")}` : ""}`}
|
title={`${label}: ${layer.count} entități${isEnriched ? `, ${layer.enrichedCount} îmbogățite` : ""}${layer.lastSynced ? `, sync: ${new Date(layer.lastSynced).toLocaleDateString("ro-RO")}` : ""}`}
|
||||||
>
|
>
|
||||||
<span className="truncate max-w-[120px]">
|
<span className="truncate max-w-[120px]">
|
||||||
{label}
|
{label}
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ export function ExportTab({
|
|||||||
phase: "Finalizat",
|
phase: "Finalizat",
|
||||||
downloaded: prev.total ?? 100,
|
downloaded: prev.total ?? 100,
|
||||||
total: prev.total ?? 100,
|
total: prev.total ?? 100,
|
||||||
message: `Desc\u0103rcare complet\u0103 \u2014 ${filename}`,
|
message: `Descărcare completă — ${filename}`,
|
||||||
note: undefined,
|
note: undefined,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
@@ -365,7 +365,7 @@ export function ExportTab({
|
|||||||
err instanceof DOMException && err.name === "AbortError";
|
err instanceof DOMException && err.name === "AbortError";
|
||||||
if (isTimeout) {
|
if (isTimeout) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"[no-geom-scan] Timeout after 2 min \u2014 server eTerra lent",
|
"[no-geom-scan] Timeout after 2 min — server eTerra lent",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setNoGeomScan({
|
setNoGeomScan({
|
||||||
@@ -469,7 +469,7 @@ export function ExportTab({
|
|||||||
} else if (data.status === "done") {
|
} else if (data.status === "done") {
|
||||||
setBgJobId(saved.jobId);
|
setBgJobId(saved.jobId);
|
||||||
setBgProgress(data);
|
setBgProgress(data);
|
||||||
if (data.phase) setBgPhaseTrail(["Sincronizare complet\u0103"]);
|
if (data.phase) setBgPhaseTrail(["Sincronizare completă"]);
|
||||||
localStorage.removeItem("parcel-sync:bg-job");
|
localStorage.removeItem("parcel-sync:bg-job");
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem("parcel-sync:bg-job");
|
localStorage.removeItem("parcel-sync:bg-job");
|
||||||
@@ -532,7 +532,7 @@ export function ExportTab({
|
|||||||
}
|
}
|
||||||
startBgPolling(jid);
|
startBgPolling(jid);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const msg = error instanceof Error ? error.message : "Eroare re\u021bea";
|
const msg = error instanceof Error ? error.message : "Eroare rețea";
|
||||||
console.warn("[sync-background]", msg);
|
console.warn("[sync-background]", msg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -573,7 +573,7 @@ export function ExportTab({
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const msg =
|
const msg =
|
||||||
error instanceof Error ? error.message : "Eroare desc\u0103rcare";
|
error instanceof Error ? error.message : "Eroare descărcare";
|
||||||
console.warn("[download-from-db]", msg);
|
console.warn("[download-from-db]", msg);
|
||||||
}
|
}
|
||||||
setDownloadingFromDb(false);
|
setDownloadingFromDb(false);
|
||||||
@@ -597,7 +597,7 @@ export function ExportTab({
|
|||||||
<span className="font-medium text-foreground">
|
<span className="font-medium text-foreground">
|
||||||
{dbTotalFeatures.toLocaleString("ro-RO")}
|
{dbTotalFeatures.toLocaleString("ro-RO")}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
entit\u0103\u021bi \u00een DB din{" "}
|
entități în DB din{" "}
|
||||||
<span className="font-medium text-foreground">
|
<span className="font-medium text-foreground">
|
||||||
{dbLayersSummary.length}
|
{dbLayersSummary.length}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
@@ -664,10 +664,10 @@ export function ExportTab({
|
|||||||
)}
|
)}
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="font-semibold">
|
<div className="font-semibold">
|
||||||
Descarc\u0103 Terenuri \u0219i Cl\u0103diri
|
Descarcă Terenuri și Clădiri
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs opacity-70 font-normal">
|
<div className="text-xs opacity-70 font-normal">
|
||||||
Sync + GPKG (din cache dac\u0103 e proasp\u0103t)
|
Sync + GPKG (din cache dacă e proaspăt)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -686,7 +686,7 @@ export function ExportTab({
|
|||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="font-semibold">Magic</div>
|
<div className="font-semibold">Magic</div>
|
||||||
<div className="text-xs opacity-70 font-normal">
|
<div className="text-xs opacity-70 font-normal">
|
||||||
Sync + \u00eembog\u0103\u021bire (CF, proprietari, adres\u0103) + GPKG + CSV
|
Sync + îmbogățire (CF, proprietari, adresă) + GPKG + CSV
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -697,12 +697,12 @@ export function ExportTab({
|
|||||||
{!session.connected ? (
|
{!session.connected ? (
|
||||||
<>
|
<>
|
||||||
<Wifi className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<Wifi className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>Conecteaz\u0103-te la eTerra pentru a activa exportul.</p>
|
<p>Conectează-te la eTerra pentru a activa exportul.</p>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<MapPin className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<MapPin className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>Selecteaz\u0103 un UAT pentru a activa exportul.</p>
|
<p>Selectează un UAT pentru a activa exportul.</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -730,10 +730,10 @@ export function ExportTab({
|
|||||||
<CardContent className="py-3 px-4">
|
<CardContent className="py-3 px-4">
|
||||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
<Loader2 className="h-4 w-4 animate-spin text-amber-500" />
|
<Loader2 className="h-4 w-4 animate-spin text-amber-500" />
|
||||||
Se scaneaz\u0103 lista de imobile din eTerra\u2026 (max 2 min)
|
Se scanează lista de imobile din eTerra… (max 2 min)
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[11px] text-muted-foreground mt-1 ml-6">
|
<p className="text-[11px] text-muted-foreground mt-1 ml-6">
|
||||||
Po\u021bi folosi butoanele de mai jos f\u0103r\u0103 s\u0103 a\u0219tep\u021bi scanarea.
|
Poți folosi butoanele de mai jos fără să aștepți scanarea.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -746,10 +746,10 @@ export function ExportTab({
|
|||||||
<CardContent className="py-3 px-4">
|
<CardContent className="py-3 px-4">
|
||||||
<div className="flex items-center gap-2 text-sm text-amber-600 dark:text-amber-400">
|
<div className="flex items-center gap-2 text-sm text-amber-600 dark:text-amber-400">
|
||||||
<Clock className="h-4 w-4 shrink-0" />
|
<Clock className="h-4 w-4 shrink-0" />
|
||||||
Scanarea a dep\u0103\u0219it 2 minute \u2014 serverul eTerra e lent.
|
Scanarea a depășit 2 minute — serverul eTerra e lent.
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[11px] text-muted-foreground mt-1 ml-6">
|
<p className="text-[11px] text-muted-foreground mt-1 ml-6">
|
||||||
Po\u021bi lansa sincronizarea fundal f\u0103r\u0103 rezultate de scanare.
|
Poți lansa sincronizarea fundal fără rezultate de scanare.
|
||||||
Include no-geom nu va fi disponibil.
|
Include no-geom nu va fi disponibil.
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
@@ -759,7 +759,7 @@ export function ExportTab({
|
|||||||
onClick={() => void handleNoGeomScan()}
|
onClick={() => void handleNoGeomScan()}
|
||||||
>
|
>
|
||||||
<RefreshCw className="h-3 w-3 mr-1" />
|
<RefreshCw className="h-3 w-3 mr-1" />
|
||||||
Re\u00eencearc\u0103 scanarea
|
Reîncearcă scanarea
|
||||||
</Button>
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -779,7 +779,7 @@ export function ExportTab({
|
|||||||
<div className="flex items-center gap-1.5 flex-wrap text-[11px] text-muted-foreground">
|
<div className="flex items-center gap-1.5 flex-wrap text-[11px] text-muted-foreground">
|
||||||
<Database className="h-3 w-3 shrink-0" />
|
<Database className="h-3 w-3 shrink-0" />
|
||||||
<span>
|
<span>
|
||||||
Baza de date local\u0103:{" "}
|
Baza de date locală:{" "}
|
||||||
<span className="font-medium text-foreground">
|
<span className="font-medium text-foreground">
|
||||||
{noGeomScan.localDbWithGeom.toLocaleString("ro-RO")}
|
{noGeomScan.localDbWithGeom.toLocaleString("ro-RO")}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
@@ -790,16 +790,16 @@ export function ExportTab({
|
|||||||
<span className="font-medium text-amber-600 dark:text-amber-400">
|
<span className="font-medium text-amber-600 dark:text-amber-400">
|
||||||
{noGeomScan.localDbNoGeom.toLocaleString("ro-RO")}
|
{noGeomScan.localDbNoGeom.toLocaleString("ro-RO")}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
f\u0103r\u0103 geometrie
|
fără geometrie
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{noGeomScan.localDbEnriched > 0 && (
|
{noGeomScan.localDbEnriched > 0 && (
|
||||||
<>
|
<>
|
||||||
{" \u00b7 "}
|
{" · "}
|
||||||
<span className="font-medium text-teal-600 dark:text-teal-400">
|
<span className="font-medium text-teal-600 dark:text-teal-400">
|
||||||
{noGeomScan.localDbEnriched.toLocaleString("ro-RO")}
|
{noGeomScan.localDbEnriched.toLocaleString("ro-RO")}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
\u00eembog\u0103\u021bite
|
îmbogățite
|
||||||
{staleEnrichment && (
|
{staleEnrichment && (
|
||||||
<span className="text-orange-600 dark:text-orange-400">
|
<span className="text-orange-600 dark:text-orange-400">
|
||||||
{" "}
|
{" "}
|
||||||
@@ -810,7 +810,7 @@ export function ExportTab({
|
|||||||
)}
|
)}
|
||||||
{noGeomScan.localSyncFresh && (
|
{noGeomScan.localSyncFresh && (
|
||||||
<span className="text-emerald-600 dark:text-emerald-400 ml-1">
|
<span className="text-emerald-600 dark:text-emerald-400 ml-1">
|
||||||
(proasp\u0103t)
|
(proaspăt)
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@@ -819,9 +819,9 @@ export function ExportTab({
|
|||||||
<div className="flex items-center gap-1.5 text-[11px] text-orange-600 dark:text-orange-400 ml-[18px]">
|
<div className="flex items-center gap-1.5 text-[11px] text-orange-600 dark:text-orange-400 ml-[18px]">
|
||||||
<AlertTriangle className="h-3 w-3 shrink-0" />
|
<AlertTriangle className="h-3 w-3 shrink-0" />
|
||||||
<span>
|
<span>
|
||||||
{staleCount.toLocaleString("ro-RO")} parcele au \u00eembog\u0103\u021bire
|
{staleCount.toLocaleString("ro-RO")} parcele au îmbogățire
|
||||||
veche (lips\u0103 PROPRIETARI_VECHI). Vor fi re-\u00eembog\u0103\u021bite la
|
veche (lipsă PROPRIETARI_VECHI). Vor fi re-îmbogățite la
|
||||||
urm\u0103torul export Magic.
|
următorul export Magic.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -832,11 +832,11 @@ export function ExportTab({
|
|||||||
const workflowPreview = scanDone && (
|
const workflowPreview = scanDone && (
|
||||||
<div className="mt-2 ml-7 space-y-0.5">
|
<div className="mt-2 ml-7 space-y-0.5">
|
||||||
<p className="text-[11px] font-medium text-muted-foreground">
|
<p className="text-[11px] font-medium text-muted-foreground">
|
||||||
La ap\u0103sarea Magic, pa\u0219ii vor fi:
|
La apăsarea Magic, pașii vor fi:
|
||||||
</p>
|
</p>
|
||||||
<ol className="text-[11px] text-muted-foreground list-decimal ml-4 space-y-px">
|
<ol className="text-[11px] text-muted-foreground list-decimal ml-4 space-y-px">
|
||||||
<li>
|
<li>
|
||||||
{"Sync GIS \u2014 "}
|
{"Sync GIS — "}
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"font-medium",
|
"font-medium",
|
||||||
@@ -848,16 +848,16 @@ export function ExportTab({
|
|||||||
>
|
>
|
||||||
{noGeomScan.localSyncFresh &&
|
{noGeomScan.localSyncFresh &&
|
||||||
noGeomScan.localDbWithGeom > 0
|
noGeomScan.localDbWithGeom > 0
|
||||||
? "skip (date proaspete \u00een DB)"
|
? "skip (date proaspete în DB)"
|
||||||
: `descarc\u0103 ${noGeomScan.remoteGisCount.toLocaleString("ro-RO")} terenuri` +
|
: `descarcă ${noGeomScan.remoteGisCount.toLocaleString("ro-RO")} terenuri` +
|
||||||
(noGeomScan.remoteCladiriCount > 0
|
(noGeomScan.remoteCladiriCount > 0
|
||||||
? ` + ${noGeomScan.remoteCladiriCount.toLocaleString("ro-RO")} cl\u0103diri`
|
? ` + ${noGeomScan.remoteCladiriCount.toLocaleString("ro-RO")} clădiri`
|
||||||
: "")}
|
: "")}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
{includeNoGeom && (
|
{includeNoGeom && (
|
||||||
<li>
|
<li>
|
||||||
Import parcele f\u0103r\u0103 geometrie \u2014{" "}
|
Import parcele fără geometrie —{" "}
|
||||||
<span className="font-medium text-amber-600 dark:text-amber-400">
|
<span className="font-medium text-amber-600 dark:text-amber-400">
|
||||||
{(() => {
|
{(() => {
|
||||||
const usefulNoGeom =
|
const usefulNoGeom =
|
||||||
@@ -878,7 +878,7 @@ export function ExportTab({
|
|||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
<li>
|
<li>
|
||||||
\u00cembog\u0103\u021bire CF, proprietari, adrese \u2014{" "}
|
\u00cembogățire CF, proprietari, adrese —{" "}
|
||||||
<span className="font-medium text-teal-600 dark:text-teal-400">
|
<span className="font-medium text-teal-600 dark:text-teal-400">
|
||||||
{(() => {
|
{(() => {
|
||||||
// What will be in DB after sync + optional no-geom import:
|
// What will be in DB after sync + optional no-geom import:
|
||||||
@@ -900,12 +900,12 @@ export function ExportTab({
|
|||||||
totalAfter - noGeomScan.localDbEnrichedComplete;
|
totalAfter - noGeomScan.localDbEnrichedComplete;
|
||||||
return remaining > 0
|
return remaining > 0
|
||||||
? `~${remaining.toLocaleString("ro-RO")} de procesat (~${Math.ceil((remaining * 0.25) / 60)} min)`
|
? `~${remaining.toLocaleString("ro-RO")} de procesat (~${Math.ceil((remaining * 0.25) / 60)} min)`
|
||||||
: "deja \u00eembog\u0103\u021bite";
|
: "deja îmbogățite";
|
||||||
})()}
|
})()}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li>Generare GPKG + CSV</li>
|
<li>Generare GPKG + CSV</li>
|
||||||
<li>Comprimare ZIP + desc\u0103rcare</li>
|
<li>Comprimare ZIP + descărcare</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -939,10 +939,10 @@ export function ExportTab({
|
|||||||
"ro-RO",
|
"ro-RO",
|
||||||
)}
|
)}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
cl\u0103diri
|
clădiri
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{" \u00b7 "}
|
{" · "}
|
||||||
Lista imobile:{" "}
|
Lista imobile:{" "}
|
||||||
<span className="font-semibold">
|
<span className="font-semibold">
|
||||||
{noGeomScan.totalImmovables.toLocaleString("ro-RO")}
|
{noGeomScan.totalImmovables.toLocaleString("ro-RO")}
|
||||||
@@ -956,11 +956,11 @@ export function ExportTab({
|
|||||||
noGeomScan.remoteGisCount,
|
noGeomScan.remoteGisCount,
|
||||||
).toLocaleString("ro-RO")}
|
).toLocaleString("ro-RO")}
|
||||||
</span>
|
</span>
|
||||||
{" f\u0103r\u0103 geometrie)"}
|
{" fără geometrie)"}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[11px] text-muted-foreground mt-0.5">
|
<p className="text-[11px] text-muted-foreground mt-0.5">
|
||||||
Cele f\u0103r\u0103 geometrie exist\u0103 \u00een baza de date eTerra dar
|
Cele fără geometrie există în baza de date eTerra dar
|
||||||
nu au contur desenat \u00een layerul GIS.
|
nu au contur desenat în layerul GIS.
|
||||||
</p>
|
</p>
|
||||||
{localDbLine}
|
{localDbLine}
|
||||||
</div>
|
</div>
|
||||||
@@ -984,7 +984,7 @@ export function ExportTab({
|
|||||||
className="h-4 w-4 rounded border-muted-foreground/30 accent-amber-600"
|
className="h-4 w-4 rounded border-muted-foreground/30 accent-amber-600"
|
||||||
/>
|
/>
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
Include \u0219i parcelele f\u0103r\u0103 geometrie la export
|
Include și parcelele fără geometrie la export
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
{/* Quality breakdown of no-geom items */}
|
{/* Quality breakdown of no-geom items */}
|
||||||
@@ -992,7 +992,7 @@ export function ExportTab({
|
|||||||
<div className="ml-7 p-2 rounded-md bg-muted/40 space-y-1">
|
<div className="ml-7 p-2 rounded-md bg-muted/40 space-y-1">
|
||||||
<p className="text-[11px] font-medium text-muted-foreground">
|
<p className="text-[11px] font-medium text-muted-foreground">
|
||||||
Calitate date (din{" "}
|
Calitate date (din{" "}
|
||||||
{noGeomScan.noGeomCount.toLocaleString("ro-RO")} f\u0103r\u0103
|
{noGeomScan.noGeomCount.toLocaleString("ro-RO")} fără
|
||||||
geometrie):
|
geometrie):
|
||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-2 gap-x-4 gap-y-0.5 text-[11px] text-muted-foreground">
|
<div className="grid grid-cols-2 gap-x-4 gap-y-0.5 text-[11px] text-muted-foreground">
|
||||||
@@ -1013,7 +1013,7 @@ export function ExportTab({
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
Cu nr. cad. pe h\u00e2rtie:{" "}
|
Cu nr. cad. pe hârtie:{" "}
|
||||||
<span className="font-medium text-foreground">
|
<span className="font-medium text-foreground">
|
||||||
{noGeomScan.qualityBreakdown.withPaperCad.toLocaleString(
|
{noGeomScan.qualityBreakdown.withPaperCad.toLocaleString(
|
||||||
"ro-RO",
|
"ro-RO",
|
||||||
@@ -1021,7 +1021,7 @@ export function ExportTab({
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
Cu suprafa\u021b\u0103:{" "}
|
Cu suprafață:{" "}
|
||||||
<span className="font-medium text-foreground">
|
<span className="font-medium text-foreground">
|
||||||
{noGeomScan.qualityBreakdown.withArea.toLocaleString(
|
{noGeomScan.qualityBreakdown.withArea.toLocaleString(
|
||||||
"ro-RO",
|
"ro-RO",
|
||||||
@@ -1037,7 +1037,7 @@ export function ExportTab({
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
Cu carte funciar\u0103:{" "}
|
Cu carte funciară:{" "}
|
||||||
<span className="font-medium text-foreground">
|
<span className="font-medium text-foreground">
|
||||||
{noGeomScan.qualityBreakdown.withLandbook.toLocaleString(
|
{noGeomScan.qualityBreakdown.withLandbook.toLocaleString(
|
||||||
"ro-RO",
|
"ro-RO",
|
||||||
@@ -1056,7 +1056,7 @@ export function ExportTab({
|
|||||||
</span>
|
</span>
|
||||||
{noGeomScan.qualityBreakdown.empty > 0 && (
|
{noGeomScan.qualityBreakdown.empty > 0 && (
|
||||||
<span>
|
<span>
|
||||||
Filtrate (f\u0103r\u0103 CF/inactive/f\u0103r\u0103 date):{" "}
|
Filtrate (fără CF/inactive/fără date):{" "}
|
||||||
<span className="font-semibold text-rose-600 dark:text-rose-400">
|
<span className="font-semibold text-rose-600 dark:text-rose-400">
|
||||||
{noGeomScan.qualityBreakdown.empty.toLocaleString(
|
{noGeomScan.qualityBreakdown.empty.toLocaleString(
|
||||||
"ro-RO",
|
"ro-RO",
|
||||||
@@ -1070,9 +1070,9 @@ export function ExportTab({
|
|||||||
{includeNoGeom && (
|
{includeNoGeom && (
|
||||||
<p className="text-[11px] text-muted-foreground ml-7">
|
<p className="text-[11px] text-muted-foreground ml-7">
|
||||||
{noGeomScan.qualityBreakdown.empty > 0
|
{noGeomScan.qualityBreakdown.empty > 0
|
||||||
? `Din ${noGeomScan.noGeomCount.toLocaleString("ro-RO")} f\u0103r\u0103 geometrie, ~${noGeomScan.qualityBreakdown.useful.toLocaleString("ro-RO")} vor fi importate (imobile electronice cu CF). ${noGeomScan.qualityBreakdown.empty.toLocaleString("ro-RO")} vor fi filtrate (f\u0103r\u0103 carte funciar\u0103, inactive sau f\u0103r\u0103 date).`
|
? `Din ${noGeomScan.noGeomCount.toLocaleString("ro-RO")} fără geometrie, ~${noGeomScan.qualityBreakdown.useful.toLocaleString("ro-RO")} vor fi importate (imobile electronice cu CF). ${noGeomScan.qualityBreakdown.empty.toLocaleString("ro-RO")} vor fi filtrate (fără carte funciară, inactive sau fără date).`
|
||||||
: "Vor fi importate \u00een DB \u0219i incluse \u00een CSV + Magic GPKG (coloana HAS_GEOMETRY=0/1)."}{" "}
|
: "Vor fi importate în DB și incluse în CSV + Magic GPKG (coloana HAS_GEOMETRY=0/1)."}{" "}
|
||||||
\u00cen GPKG de baz\u0103 apar doar cele cu geometrie.
|
\u00cen GPKG de bază apar doar cele cu geometrie.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{workflowPreview}
|
{workflowPreview}
|
||||||
@@ -1091,14 +1091,14 @@ export function ExportTab({
|
|||||||
<CheckCircle2 className="h-3.5 w-3.5 text-emerald-500" />
|
<CheckCircle2 className="h-3.5 w-3.5 text-emerald-500" />
|
||||||
Toate cele{" "}
|
Toate cele{" "}
|
||||||
{noGeomScan.totalImmovables.toLocaleString("ro-RO")}{" "}
|
{noGeomScan.totalImmovables.toLocaleString("ro-RO")}{" "}
|
||||||
imobile din eTerra au geometrie \u2014 nimic de importat
|
imobile din eTerra au geometrie — nimic de importat
|
||||||
suplimentar.
|
suplimentar.
|
||||||
{noGeomScan.localDbTotal > 0 && (
|
{noGeomScan.localDbTotal > 0 && (
|
||||||
<span className="ml-1">
|
<span className="ml-1">
|
||||||
({noGeomScan.localDbTotal.toLocaleString("ro-RO")}{" "}
|
({noGeomScan.localDbTotal.toLocaleString("ro-RO")}{" "}
|
||||||
\u00een DB local
|
în DB local
|
||||||
{noGeomScan.localDbEnriched > 0 &&
|
{noGeomScan.localDbEnriched > 0 &&
|
||||||
`, ${noGeomScan.localDbEnriched.toLocaleString("ro-RO")} \u00eembog\u0103\u021bite`}
|
`, ${noGeomScan.localDbEnriched.toLocaleString("ro-RO")} îmbogățite`}
|
||||||
{noGeomScan.localDbEnriched > 0 &&
|
{noGeomScan.localDbEnriched > 0 &&
|
||||||
noGeomScan.localDbEnrichedComplete <
|
noGeomScan.localDbEnrichedComplete <
|
||||||
noGeomScan.localDbEnriched && (
|
noGeomScan.localDbEnriched && (
|
||||||
@@ -1106,15 +1106,15 @@ export function ExportTab({
|
|||||||
{` (${(noGeomScan.localDbEnriched - noGeomScan.localDbEnrichedComplete).toLocaleString("ro-RO")} incomplete)`}
|
{` (${(noGeomScan.localDbEnriched - noGeomScan.localDbEnrichedComplete).toLocaleString("ro-RO")} incomplete)`}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{noGeomScan.localSyncFresh && ", proasp\u0103t"})
|
{noGeomScan.localSyncFresh && ", proaspăt"})
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<AlertTriangle className="h-3.5 w-3.5 text-muted-foreground" />
|
<AlertTriangle className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
Nu s-au g\u0103sit imobile \u00een lista eTerra pentru acest
|
Nu s-au găsit imobile în lista eTerra pentru acest
|
||||||
UAT. Verific\u0103 sesiunea eTerra.
|
UAT. Verifică sesiunea eTerra.
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -1133,10 +1133,10 @@ export function ExportTab({
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
Procesare fundal & desc\u0103rcare din DB
|
Procesare fundal & descărcare din DB
|
||||||
</span>
|
</span>
|
||||||
<span className="text-[10px] text-muted-foreground">
|
<span className="text-[10px] text-muted-foreground">
|
||||||
\u2014 porne\u0219te sincronizarea, \u00eenchide pagina, descarc\u0103 mai t\u00e2rziu
|
— pornește sincronizarea, închide pagina, descarcă mai târziu
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1154,11 +1154,11 @@ export function ExportTab({
|
|||||||
className="h-4 w-4 rounded border-muted-foreground/30 accent-amber-600"
|
className="h-4 w-4 rounded border-muted-foreground/30 accent-amber-600"
|
||||||
/>
|
/>
|
||||||
<span className="text-xs">
|
<span className="text-xs">
|
||||||
Include \u0219i parcelele f\u0103r\u0103 geometrie
|
Include și parcelele fără geometrie
|
||||||
</span>
|
</span>
|
||||||
{noGeomScanning && (
|
{noGeomScanning && (
|
||||||
<span className="text-[10px] text-muted-foreground">
|
<span className="text-[10px] text-muted-foreground">
|
||||||
(scanare \u00een curs\u2026)
|
(scanare în curs…)
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</label>
|
</label>
|
||||||
@@ -1179,17 +1179,17 @@ export function ExportTab({
|
|||||||
>
|
>
|
||||||
{bgJobId &&
|
{bgJobId &&
|
||||||
bgProgress?.status === "running" &&
|
bgProgress?.status === "running" &&
|
||||||
!bgPhaseTrail.some((p) => p.includes("\u00cembog\u0103\u021bire")) ? (
|
!bgPhaseTrail.some((p) => p.includes("\u00cembogățire")) ? (
|
||||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||||
) : (
|
) : (
|
||||||
<ArrowDownToLine className="mr-2 h-4 w-4" />
|
<ArrowDownToLine className="mr-2 h-4 w-4" />
|
||||||
)}
|
)}
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="text-xs font-semibold">
|
<div className="text-xs font-semibold">
|
||||||
Sync fundal \u2014 Baz\u0103
|
Sync fundal — Bază
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[10px] opacity-60 font-normal">
|
<div className="text-[10px] opacity-60 font-normal">
|
||||||
Terenuri + cl\u0103diri \u2192 salveaz\u0103 \u00een DB
|
Terenuri + clădiri \u2192 salvează în DB
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -1205,17 +1205,17 @@ export function ExportTab({
|
|||||||
>
|
>
|
||||||
{bgJobId &&
|
{bgJobId &&
|
||||||
bgProgress?.status === "running" &&
|
bgProgress?.status === "running" &&
|
||||||
bgPhaseTrail.some((p) => p.includes("\u00cembog\u0103\u021bire")) ? (
|
bgPhaseTrail.some((p) => p.includes("\u00cembogățire")) ? (
|
||||||
<Loader2 className="mr-2 h-4 w-4 animate-spin text-teal-600" />
|
<Loader2 className="mr-2 h-4 w-4 animate-spin text-teal-600" />
|
||||||
) : (
|
) : (
|
||||||
<Sparkles className="mr-2 h-4 w-4 text-teal-600" />
|
<Sparkles className="mr-2 h-4 w-4 text-teal-600" />
|
||||||
)}
|
)}
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="text-xs font-semibold">
|
<div className="text-xs font-semibold">
|
||||||
Sync fundal \u2014 Magic
|
Sync fundal — Magic
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[10px] opacity-60 font-normal">
|
<div className="text-[10px] opacity-60 font-normal">
|
||||||
Sync + \u00eembog\u0103\u021bire \u2192 salveaz\u0103 \u00een DB
|
Sync + îmbogățire \u2192 salvează în DB
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -1239,10 +1239,10 @@ export function ExportTab({
|
|||||||
)}
|
)}
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="text-xs font-semibold">
|
<div className="text-xs font-semibold">
|
||||||
Descarc\u0103 din DB \u2014 Baz\u0103
|
Descarcă din DB — Bază
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[10px] opacity-60 font-normal">
|
<div className="text-[10px] opacity-60 font-normal">
|
||||||
GPKG terenuri + cl\u0103diri (instant, f\u0103r\u0103 eTerra)
|
GPKG terenuri + clădiri (instant, fără eTerra)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -1260,7 +1260,7 @@ export function ExportTab({
|
|||||||
)}
|
)}
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<div className="text-xs font-semibold">
|
<div className="text-xs font-semibold">
|
||||||
Descarc\u0103 din DB \u2014 Magic
|
Descarcă din DB — Magic
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[10px] opacity-60 font-normal">
|
<div className="text-[10px] opacity-60 font-normal">
|
||||||
GPKG + CSV + raport calitate (instant)
|
GPKG + CSV + raport calitate (instant)
|
||||||
@@ -1272,8 +1272,8 @@ export function ExportTab({
|
|||||||
|
|
||||||
{!session.connected && dbTotalFeatures === 0 && (
|
{!session.connected && dbTotalFeatures === 0 && (
|
||||||
<p className="text-xs text-muted-foreground ml-6">
|
<p className="text-xs text-muted-foreground ml-6">
|
||||||
Conecteaz\u0103-te la eTerra pentru a porni sincronizarea fundal,
|
Conectează-te la eTerra pentru a porni sincronizarea fundal,
|
||||||
sau sincronizeaz\u0103 mai \u00eent\u00e2i date \u00een baza local\u0103.
|
sau sincronizează mai întâi date în baza locală.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -1302,7 +1302,7 @@ export function ExportTab({
|
|||||||
</span>
|
</span>
|
||||||
{bgProgress.status === "running" && (
|
{bgProgress.status === "running" && (
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground">
|
||||||
(po\u021bi \u00eenchide pagina)
|
(poți închide pagina)
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -1396,7 +1396,7 @@ export function ExportTab({
|
|||||||
) : (
|
) : (
|
||||||
<Database className="mr-1.5 h-3 w-3" />
|
<Database className="mr-1.5 h-3 w-3" />
|
||||||
)}
|
)}
|
||||||
Descarc\u0103 din DB (Magic)
|
Descarcă din DB (Magic)
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@@ -1466,7 +1466,7 @@ export function ExportTab({
|
|||||||
{exportProgress.phase}
|
{exportProgress.phase}
|
||||||
{exportProgress.phaseCurrent != null &&
|
{exportProgress.phaseCurrent != null &&
|
||||||
exportProgress.phaseTotal
|
exportProgress.phaseTotal
|
||||||
? ` \u2014 ${exportProgress.phaseCurrent} / ${exportProgress.phaseTotal}`
|
? ` — ${exportProgress.phaseCurrent} / ${exportProgress.phaseTotal}`
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
{exportProgress.note && (
|
{exportProgress.note && (
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ export function LayersTab({
|
|||||||
async (layerId: string) => {
|
async (layerId: string) => {
|
||||||
if (!siruta || syncingLayer) return;
|
if (!siruta || syncingLayer) return;
|
||||||
setSyncingLayer(layerId);
|
setSyncingLayer(layerId);
|
||||||
setSyncProgress("Sincronizare pornit\u0103\u2026");
|
setSyncProgress("Sincronizare pornită…");
|
||||||
try {
|
try {
|
||||||
const res = await fetch("/api/eterra/sync", {
|
const res = await fetch("/api/eterra/sync", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -261,13 +261,13 @@ export function LayersTab({
|
|||||||
setSyncProgress(`Eroare: ${data.error}`);
|
setSyncProgress(`Eroare: ${data.error}`);
|
||||||
} else {
|
} else {
|
||||||
setSyncProgress(
|
setSyncProgress(
|
||||||
`Finalizat \u2014 ${data.newFeatures ?? 0} noi, ${data.removedFeatures ?? 0} \u0219terse, ${data.totalLocal ?? 0} total local`,
|
`Finalizat — ${data.newFeatures ?? 0} noi, ${data.removedFeatures ?? 0} șterse, ${data.totalLocal ?? 0} total local`,
|
||||||
);
|
);
|
||||||
// Refresh sync status
|
// Refresh sync status
|
||||||
onSyncRefresh();
|
onSyncRefresh();
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setSyncProgress("Eroare re\u021bea");
|
setSyncProgress("Eroare rețea");
|
||||||
}
|
}
|
||||||
// Clear progress after 8s
|
// Clear progress after 8s
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -334,7 +334,7 @@ export function LayersTab({
|
|||||||
for (const layerId of layerIds) {
|
for (const layerId of layerIds) {
|
||||||
setSyncingLayer(layerId);
|
setSyncingLayer(layerId);
|
||||||
setSyncProgress(
|
setSyncProgress(
|
||||||
`Sincronizare ${LAYER_CATALOG.find((l) => l.id === layerId)?.label ?? layerId}\u2026`,
|
`Sincronizare ${LAYER_CATALOG.find((l) => l.id === layerId)?.label ?? layerId}…`,
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
const res = await fetch("/api/eterra/sync", {
|
const res = await fetch("/api/eterra/sync", {
|
||||||
@@ -356,7 +356,7 @@ export function LayersTab({
|
|||||||
setSyncProgress(`Eroare: ${data.error}`);
|
setSyncProgress(`Eroare: ${data.error}`);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setSyncProgress("Eroare re\u021bea");
|
setSyncProgress("Eroare rețea");
|
||||||
}
|
}
|
||||||
// Remove from queue
|
// Remove from queue
|
||||||
syncQueueRef.current = syncQueueRef.current.filter(
|
syncQueueRef.current = syncQueueRef.current.filter(
|
||||||
@@ -445,7 +445,7 @@ export function LayersTab({
|
|||||||
phase: "Finalizat",
|
phase: "Finalizat",
|
||||||
downloaded: prev.total ?? 100,
|
downloaded: prev.total ?? 100,
|
||||||
total: prev.total ?? 100,
|
total: prev.total ?? 100,
|
||||||
message: `Desc\u0103rcare complet\u0103 \u2014 ${filename}`,
|
message: `Descărcare completă — ${filename}`,
|
||||||
note: undefined,
|
note: undefined,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
@@ -489,8 +489,8 @@ export function LayersTab({
|
|||||||
<Layers className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<Layers className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>
|
<p>
|
||||||
{!session.connected
|
{!session.connected
|
||||||
? "Conecteaz\u0103-te la eTerra \u0219i selecteaz\u0103 un UAT."
|
? "Conectează-te la eTerra și selectează un UAT."
|
||||||
: "Selecteaz\u0103 un UAT pentru a vedea catalogul de layere."}
|
: "Selectează un UAT pentru a vedea catalogul de layere."}
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -504,8 +504,8 @@ export function LayersTab({
|
|||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
{layerCountSiruta === siruta &&
|
{layerCountSiruta === siruta &&
|
||||||
Object.keys(layerCounts).length > 0
|
Object.keys(layerCounts).length > 0
|
||||||
? `Num\u0103r features pentru SIRUTA ${siruta}`
|
? `Număr features pentru SIRUTA ${siruta}`
|
||||||
: "Apas\u0103 pentru a num\u0103ra features-urile din fiecare layer."}
|
: "Apasă pentru a număra features-urile din fiecare layer."}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{/* Export from local DB */}
|
{/* Export from local DB */}
|
||||||
@@ -537,7 +537,7 @@ export function LayersTab({
|
|||||||
) : (
|
) : (
|
||||||
<Search className="h-3.5 w-3.5 mr-1.5" />
|
<Search className="h-3.5 w-3.5 mr-1.5" />
|
||||||
)}
|
)}
|
||||||
{countingLayers ? "Se num\u0103r\u0103\u2026" : "Num\u0103r\u0103"}
|
{countingLayers ? "Se numără…" : "Numără"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -712,7 +712,7 @@ export function LayersTab({
|
|||||||
void handleSyncLayer(layer.id)
|
void handleSyncLayer(layer.id)
|
||||||
}
|
}
|
||||||
className="border-violet-200 dark:border-violet-800"
|
className="border-violet-200 dark:border-violet-800"
|
||||||
title="Sincronizeaz\u0103 \u00een baza de date"
|
title="Sincronizează în baza de date"
|
||||||
>
|
>
|
||||||
{isSyncing ? (
|
{isSyncing ? (
|
||||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||||
@@ -733,8 +733,8 @@ export function LayersTab({
|
|||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
localCount > 0
|
localCount > 0
|
||||||
? "Descarc\u0103 GPKG (din cache dac\u0103 e proasp\u0103t)"
|
? "Descarcă GPKG (din cache dacă e proaspăt)"
|
||||||
: "Sincronizeaz\u0103 + descarc\u0103 GPKG"
|
: "Sincronizează + descarcă GPKG"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{isDownloading ? (
|
{isDownloading ? (
|
||||||
@@ -787,7 +787,7 @@ export function LayersTab({
|
|||||||
<p className="text-[11px] font-semibold text-muted-foreground">
|
<p className="text-[11px] font-semibold text-muted-foreground">
|
||||||
SIRUTA {sir}{" "}
|
SIRUTA {sir}{" "}
|
||||||
<span className="font-normal opacity-70">
|
<span className="font-normal opacity-70">
|
||||||
\u2014{" "}
|
—{" "}
|
||||||
{new Date(entries[0]!.time).toLocaleTimeString(
|
{new Date(entries[0]!.time).toLocaleTimeString(
|
||||||
"ro-RO",
|
"ro-RO",
|
||||||
{ hour: "2-digit", minute: "2-digit" },
|
{ hour: "2-digit", minute: "2-digit" },
|
||||||
@@ -845,7 +845,7 @@ export function LayersTab({
|
|||||||
<Database className="h-3.5 w-3.5 mr-1.5" />
|
<Database className="h-3.5 w-3.5 mr-1.5" />
|
||||||
)}
|
)}
|
||||||
{postgisRunning
|
{postgisRunning
|
||||||
? "Se activeaza\u2026"
|
? "Se activeaza…"
|
||||||
: "Activeaza compatibilitate QGIS"}
|
: "Activeaza compatibilitate QGIS"}
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -871,7 +871,7 @@ export function LayersTab({
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<CheckCircle2 className="h-4 w-4 text-emerald-500" />
|
<CheckCircle2 className="h-4 w-4 text-emerald-500" />
|
||||||
<span className="text-sm font-medium text-emerald-700 dark:text-emerald-400">
|
<span className="text-sm font-medium text-emerald-700 dark:text-emerald-400">
|
||||||
QGIS compatibil \u2014 gata de conectare
|
QGIS compatibil — gata de conectare
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="rounded bg-muted/50 p-3 text-xs space-y-2">
|
<div className="rounded bg-muted/50 p-3 text-xs space-y-2">
|
||||||
@@ -946,7 +946,7 @@ export function LayersTab({
|
|||||||
si limitelor UAT.
|
si limitelor UAT.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Apasa butonul pentru a activa \u2014 creeaza view-uri read-only
|
Apasa butonul pentru a activa — creeaza view-uri read-only
|
||||||
(nu modifica datele, nu afecteaza performanta aplicatiei).
|
(nu modifica datele, nu afecteaza performanta aplicatiei).
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -965,7 +965,7 @@ export function LayersTab({
|
|||||||
{exportProgress.phase}
|
{exportProgress.phase}
|
||||||
{exportProgress.phaseCurrent != null &&
|
{exportProgress.phaseCurrent != null &&
|
||||||
exportProgress.phaseTotal
|
exportProgress.phaseTotal
|
||||||
? ` \u2014 ${exportProgress.phaseCurrent} / ${exportProgress.phaseTotal}`
|
? ` — ${exportProgress.phaseCurrent} / ${exportProgress.phaseTotal}`
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<MapIcon className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<MapIcon className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>Selecteaz\u0103 un UAT din lista de mai sus</p>
|
<p>Selectează un UAT din lista de mai sus</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
@@ -332,7 +332,7 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
|
|||||||
{boundsLoading && (
|
{boundsLoading && (
|
||||||
<div className="absolute top-3 left-1/2 -translate-x-1/2 z-20 flex items-center gap-2 rounded-full bg-background/90 border px-3 py-1.5 text-xs shadow-sm">
|
<div className="absolute top-3 left-1/2 -translate-x-1/2 z-20 flex items-center gap-2 rounded-full bg-background/90 border px-3 py-1.5 text-xs shadow-sm">
|
||||||
<Loader2 className="h-3 w-3 animate-spin" />
|
<Loader2 className="h-3 w-3 animate-spin" />
|
||||||
Se \u00eencarc\u0103 zona UAT...
|
Se încarcă zona UAT...
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
|
|||||||
<div className="absolute bottom-3 right-3 z-10 rounded-lg bg-background/90 border p-2 text-[10px] space-y-1">
|
<div className="absolute bottom-3 right-3 z-10 rounded-lg bg-background/90 border p-2 text-[10px] space-y-1">
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="inline-block h-3 w-3 rounded-sm border" style={{ backgroundColor: "rgba(134,239,172,0.25)", borderColor: "#15803d" }} />
|
<span className="inline-block h-3 w-3 rounded-sm border" style={{ backgroundColor: "rgba(134,239,172,0.25)", borderColor: "#15803d" }} />
|
||||||
F\u0103r\u0103 enrichment
|
Fără enrichment
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="inline-block h-3 w-3 rounded-sm border" style={{ backgroundColor: "rgba(21,128,61,0.25)", borderColor: "#15803d" }} />
|
<span className="inline-block h-3 w-3 rounded-sm border" style={{ backgroundColor: "rgba(21,128,61,0.25)", borderColor: "#15803d" }} />
|
||||||
@@ -384,11 +384,11 @@ export function MapTab({ siruta, sirutaValid }: MapTabProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="inline-block h-3 w-3 rounded-sm" style={{ border: "2px solid #3b82f6" }} />
|
<span className="inline-block h-3 w-3 rounded-sm" style={{ border: "2px solid #3b82f6" }} />
|
||||||
Cu cl\u0103dire
|
Cu clădire
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="inline-block h-3 w-3 rounded-sm" style={{ border: "2px solid #ef4444" }} />
|
<span className="inline-block h-3 w-3 rounded-sm" style={{ border: "2px solid #ef4444" }} />
|
||||||
Cl\u0103dire f\u0103r\u0103 acte
|
Clădire fără acte
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export function SearchTab({
|
|||||||
setSearchError("");
|
setSearchError("");
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setSearchError("Eroare de re\u021bea.");
|
setSearchError("Eroare de rețea.");
|
||||||
}
|
}
|
||||||
setLoadingFeatures(false);
|
setLoadingFeatures(false);
|
||||||
}, [siruta, featuresSearch, workspacePk]);
|
}, [siruta, featuresSearch, workspacePk]);
|
||||||
@@ -178,12 +178,12 @@ export function SearchTab({
|
|||||||
if (data.eterraNote) notes.push(data.eterraNote);
|
if (data.eterraNote) notes.push(data.eterraNote);
|
||||||
setOwnerNote(
|
setOwnerNote(
|
||||||
notes.length > 0
|
notes.length > 0
|
||||||
? `Surse: ${notes.join(" + ")}${data.total ? ` \u00b7 ${data.total} rezultate` : ""}`
|
? `Surse: ${notes.join(" + ")}${data.total ? ` · ${data.total} rezultate` : ""}`
|
||||||
: "",
|
: "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setOwnerError("Eroare de re\u021bea.");
|
setOwnerError("Eroare de rețea.");
|
||||||
}
|
}
|
||||||
setOwnerLoading(false);
|
setOwnerLoading(false);
|
||||||
}, [siruta, ownerSearch, workspacePk]);
|
}, [siruta, ownerSearch, workspacePk]);
|
||||||
@@ -596,7 +596,7 @@ export function SearchTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<Search className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<Search className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>Selecteaz\u0103 un UAT mai sus pentru a c\u0103uta parcele.</p>
|
<p>Selectează un UAT mai sus pentru a căuta parcele.</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
@@ -640,7 +640,7 @@ export function SearchTab({
|
|||||||
<div className="flex gap-3 items-end">
|
<div className="flex gap-3 items-end">
|
||||||
<div className="space-y-1 flex-1">
|
<div className="space-y-1 flex-1">
|
||||||
<Label className="text-xs">
|
<Label className="text-xs">
|
||||||
Numere cadastrale (separate prin virgul\u0103 sau Enter)
|
Numere cadastrale (separate prin virgulă sau Enter)
|
||||||
</Label>
|
</Label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||||
@@ -655,8 +655,8 @@ export function SearchTab({
|
|||||||
</div>
|
</div>
|
||||||
{!session.connected && (
|
{!session.connected && (
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
Necesit\u0103 conexiune eTerra. Folose\u0219te modul Proprietar
|
Necesită conexiune eTerra. Folosește modul Proprietar
|
||||||
pentru a c\u0103uta offline \u00een DB.
|
pentru a căuta offline în DB.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -673,7 +673,7 @@ export function SearchTab({
|
|||||||
) : (
|
) : (
|
||||||
<Search className="mr-2 h-4 w-4" />
|
<Search className="mr-2 h-4 w-4" />
|
||||||
)}
|
)}
|
||||||
Caut\u0103
|
Caută
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -683,7 +683,7 @@ export function SearchTab({
|
|||||||
<div className="flex gap-3 items-end">
|
<div className="flex gap-3 items-end">
|
||||||
<div className="space-y-1 flex-1">
|
<div className="space-y-1 flex-1">
|
||||||
<Label className="text-xs">
|
<Label className="text-xs">
|
||||||
Nume proprietar (caut\u0103 \u00een DB local + eTerra)
|
Nume proprietar (caută în DB local + eTerra)
|
||||||
</Label>
|
</Label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<User className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
<User className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||||
@@ -705,7 +705,7 @@ export function SearchTab({
|
|||||||
) : (
|
) : (
|
||||||
<Search className="mr-2 h-4 w-4" />
|
<Search className="mr-2 h-4 w-4" />
|
||||||
)}
|
)}
|
||||||
Caut\u0103
|
Caută
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -729,10 +729,10 @@ export function SearchTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<Loader2 className="h-10 w-10 mx-auto mb-3 animate-spin opacity-50" />
|
<Loader2 className="h-10 w-10 mx-auto mb-3 animate-spin opacity-50" />
|
||||||
<p>Se caut\u0103 \u00een eTerra...</p>
|
<p>Se caută în eTerra...</p>
|
||||||
<p className="text-xs mt-1 opacity-60">
|
<p className="text-xs mt-1 opacity-60">
|
||||||
Prima c\u0103utare pe un UAT nou poate dura ~10-30s (se
|
Prima căutare pe un UAT nou poate dura ~10-30s (se
|
||||||
\u00eencarc\u0103 lista de jude\u021be).
|
încarcă lista de județe).
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -747,7 +747,7 @@ export function SearchTab({
|
|||||||
{searchResults.length > 1 ? "e" : ""}
|
{searchResults.length > 1 ? "e" : ""}
|
||||||
{searchList.length > 0 && (
|
{searchList.length > 0 && (
|
||||||
<span className="ml-2">
|
<span className="ml-2">
|
||||||
· <strong>{searchList.length}</strong> \u00een list\u0103
|
· <strong>{searchList.length}</strong> în listă
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@@ -761,7 +761,7 @@ export function SearchTab({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Plus className="mr-1 h-3.5 w-3.5" />
|
<Plus className="mr-1 h-3.5 w-3.5" />
|
||||||
Adaug\u0103 toate \u00een list\u0103
|
Adaugă toate în listă
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
@@ -773,7 +773,7 @@ export function SearchTab({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FileDown className="mr-1 h-3.5 w-3.5" />
|
<FileDown className="mr-1 h-3.5 w-3.5" />
|
||||||
Descarc\u0103 CSV
|
Descarcă CSV
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -796,7 +796,7 @@ export function SearchTab({
|
|||||||
</h3>
|
</h3>
|
||||||
{!p.immovablePk && (
|
{!p.immovablePk && (
|
||||||
<p className="text-xs text-destructive">
|
<p className="text-xs text-destructive">
|
||||||
Parcela nu a fost g\u0103sit\u0103 \u00een eTerra.
|
Parcela nu a fost găsită în eTerra.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -805,7 +805,7 @@ export function SearchTab({
|
|||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="h-7 w-7 p-0"
|
className="h-7 w-7 p-0"
|
||||||
title="Adaug\u0103 \u00een list\u0103"
|
title="Adaugă în listă"
|
||||||
onClick={() => addToList(p)}
|
onClick={() => addToList(p)}
|
||||||
disabled={!p.immovablePk}
|
disabled={!p.immovablePk}
|
||||||
>
|
>
|
||||||
@@ -819,7 +819,7 @@ export function SearchTab({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
const text = [
|
const text = [
|
||||||
`Nr. Cad: ${p.nrCad}`,
|
`Nr. Cad: ${p.nrCad}`,
|
||||||
`Nr. CF: ${p.nrCF || "\u2014"}`,
|
`Nr. CF: ${p.nrCF || "—"}`,
|
||||||
p.nrCFVechi
|
p.nrCFVechi
|
||||||
? `CF vechi: ${p.nrCFVechi}`
|
? `CF vechi: ${p.nrCFVechi}`
|
||||||
: null,
|
: null,
|
||||||
@@ -829,7 +829,7 @@ export function SearchTab({
|
|||||||
p.suprafata != null
|
p.suprafata != null
|
||||||
? `Suprafata: ${p.suprafata.toLocaleString("ro-RO")} mp`
|
? `Suprafata: ${p.suprafata.toLocaleString("ro-RO")} mp`
|
||||||
: null,
|
: null,
|
||||||
`Intravilan: ${p.intravilan || "\u2014"}`,
|
`Intravilan: ${p.intravilan || "—"}`,
|
||||||
p.categorieFolosinta
|
p.categorieFolosinta
|
||||||
? `Categorie: ${p.categorieFolosinta}`
|
? `Categorie: ${p.categorieFolosinta}`
|
||||||
: null,
|
: null,
|
||||||
@@ -870,7 +870,7 @@ export function SearchTab({
|
|||||||
Nr. CF
|
Nr. CF
|
||||||
</span>
|
</span>
|
||||||
<span className="font-medium">
|
<span className="font-medium">
|
||||||
{p.nrCF || "\u2014"}
|
{p.nrCF || "—"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{p.nrCFVechi && (
|
{p.nrCFVechi && (
|
||||||
@@ -885,16 +885,16 @@ export function SearchTab({
|
|||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Nr. Topo
|
Nr. Topo
|
||||||
</span>
|
</span>
|
||||||
<span>{p.nrTopo || "\u2014"}</span>
|
<span>{p.nrTopo || "—"}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Suprafa\u021b\u0103
|
Suprafață
|
||||||
</span>
|
</span>
|
||||||
<span className="tabular-nums">
|
<span className="tabular-nums">
|
||||||
{p.suprafata != null
|
{p.suprafata != null
|
||||||
? formatArea(p.suprafata)
|
? formatArea(p.suprafata)
|
||||||
: "\u2014"}
|
: "—"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -911,13 +911,13 @@ export function SearchTab({
|
|||||||
}
|
}
|
||||||
className="text-[11px]"
|
className="text-[11px]"
|
||||||
>
|
>
|
||||||
{p.intravilan || "\u2014"}
|
{p.intravilan || "—"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
{p.categorieFolosinta && (
|
{p.categorieFolosinta && (
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Categorii folosin\u021b\u0103
|
Categorii folosință
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs">
|
<span className="text-xs">
|
||||||
{p.categorieFolosinta}
|
{p.categorieFolosinta}
|
||||||
@@ -927,7 +927,7 @@ export function SearchTab({
|
|||||||
{p.adresa && (
|
{p.adresa && (
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Adres\u0103
|
Adresă
|
||||||
</span>
|
</span>
|
||||||
<span>{p.adresa}</span>
|
<span>{p.adresa}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -991,10 +991,10 @@ export function SearchTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<Search className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<Search className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>Introdu un num\u0103r cadastral \u0219i apas\u0103 Caut\u0103.</p>
|
<p>Introdu un număr cadastral și apasă Caută.</p>
|
||||||
<p className="text-xs mt-1 opacity-60">
|
<p className="text-xs mt-1 opacity-60">
|
||||||
Po\u021bi c\u0103uta mai multe parcele simultan, separate prin
|
Poți căuta mai multe parcele simultan, separate prin
|
||||||
virgul\u0103.
|
virgulă.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -1009,9 +1009,9 @@ export function SearchTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<Loader2 className="h-10 w-10 mx-auto mb-3 animate-spin opacity-50" />
|
<Loader2 className="h-10 w-10 mx-auto mb-3 animate-spin opacity-50" />
|
||||||
<p>Se caut\u0103 proprietar...</p>
|
<p>Se caută proprietar...</p>
|
||||||
<p className="text-xs mt-1 opacity-60">
|
<p className="text-xs mt-1 opacity-60">
|
||||||
Caut\u0103 mai \u00eent\u00e2i \u00een DB local (date \u00eembog\u0103\u021bite), apoi pe
|
Caută mai întâi în DB local (date îmbogățite), apoi pe
|
||||||
eTerra.
|
eTerra.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -1036,7 +1036,7 @@ export function SearchTab({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Plus className="mr-1 h-3.5 w-3.5" />
|
<Plus className="mr-1 h-3.5 w-3.5" />
|
||||||
Adaug\u0103 toate \u00een list\u0103
|
Adaugă toate în listă
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -1047,7 +1047,7 @@ export function SearchTab({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FileDown className="mr-1 h-3.5 w-3.5" />
|
<FileDown className="mr-1 h-3.5 w-3.5" />
|
||||||
Descarc\u0103 CSV
|
Descarcă CSV
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1075,7 +1075,7 @@ export function SearchTab({
|
|||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="h-7 w-7 p-0"
|
className="h-7 w-7 p-0"
|
||||||
title="Adaug\u0103 \u00een list\u0103"
|
title="Adaugă în listă"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addToList(ownerResultToParcelDetail(r))
|
addToList(ownerResultToParcelDetail(r))
|
||||||
}
|
}
|
||||||
@@ -1128,7 +1128,7 @@ export function SearchTab({
|
|||||||
{r.suprafata && (
|
{r.suprafata && (
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Suprafa\u021b\u0103
|
Suprafață
|
||||||
</span>
|
</span>
|
||||||
<span className="tabular-nums">
|
<span className="tabular-nums">
|
||||||
{typeof r.suprafata === "number"
|
{typeof r.suprafata === "number"
|
||||||
@@ -1159,7 +1159,7 @@ export function SearchTab({
|
|||||||
{r.categorieFolosinta && (
|
{r.categorieFolosinta && (
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Categorii folosin\u021b\u0103
|
Categorii folosință
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs">
|
<span className="text-xs">
|
||||||
{r.categorieFolosinta}
|
{r.categorieFolosinta}
|
||||||
@@ -1169,7 +1169,7 @@ export function SearchTab({
|
|||||||
{r.adresa && (
|
{r.adresa && (
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<span className="text-xs text-muted-foreground block">
|
<span className="text-xs text-muted-foreground block">
|
||||||
Adres\u0103
|
Adresă
|
||||||
</span>
|
</span>
|
||||||
<span>{r.adresa}</span>
|
<span>{r.adresa}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1206,12 +1206,12 @@ export function SearchTab({
|
|||||||
<Card>
|
<Card>
|
||||||
<CardContent className="py-12 text-center text-muted-foreground">
|
<CardContent className="py-12 text-center text-muted-foreground">
|
||||||
<User className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
<User className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||||
<p>Introdu numele proprietarului \u0219i apas\u0103 Caut\u0103.</p>
|
<p>Introdu numele proprietarului și apasă Caută.</p>
|
||||||
<p className="text-xs mt-1 opacity-60">
|
<p className="text-xs mt-1 opacity-60">
|
||||||
Caut\u0103 \u00een datele \u00eembog\u0103\u021bite (DB local) \u0219i pe eTerra.
|
Caută în datele îmbogățite (DB local) și pe eTerra.
|
||||||
<br />
|
<br />
|
||||||
Pentru rezultate complete, lanseaz\u0103 "Sync fundal \u2014
|
Pentru rezultate complete, lansează "Sync fundal —
|
||||||
Magic" \u00een tab-ul Export.
|
Magic" în tab-ul Export.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -1377,15 +1377,15 @@ export function SearchTab({
|
|||||||
{p.nrCad}
|
{p.nrCad}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2 text-xs">
|
<td className="px-3 py-2 text-xs">
|
||||||
{p.nrCF || "\u2014"}
|
{p.nrCF || "—"}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2 text-right hidden sm:table-cell tabular-nums text-xs">
|
<td className="px-3 py-2 text-right hidden sm:table-cell tabular-nums text-xs">
|
||||||
{p.suprafata != null
|
{p.suprafata != null
|
||||||
? formatArea(p.suprafata)
|
? formatArea(p.suprafata)
|
||||||
: "\u2014"}
|
: "—"}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2 hidden md:table-cell text-xs truncate max-w-[300px]">
|
<td className="px-3 py-2 hidden md:table-cell text-xs truncate max-w-[300px]">
|
||||||
{p.proprietari || "\u2014"}
|
{p.proprietari || "—"}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2 text-center">
|
<td className="px-3 py-2 text-center">
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
|
|||||||
Reference in New Issue
Block a user