diff --git a/src/app/api/eterra/export-bundle/route.ts b/src/app/api/eterra/export-bundle/route.ts
index 4a4be28..a024ab5 100644
--- a/src/app/api/eterra/export-bundle/route.ts
+++ b/src/app/api/eterra/export-bundle/route.ts
@@ -562,6 +562,19 @@ export async function POST(req: Request) {
zip.file("terenuri.gpkg", terenuriGpkg);
zip.file("cladiri.gpkg", cladiriGpkg);
+ // DXF versions (non-fatal)
+ try {
+ const { gpkgToDxf } = await import(
+ "@/modules/parcel-sync/services/gpkg-export"
+ );
+ const tDxf = await gpkgToDxf(terenuriGpkg, "TERENURI_ACTIVE");
+ if (tDxf) zip.file("terenuri.dxf", tDxf);
+ const cDxf = await gpkgToDxf(cladiriGpkg, "CLADIRI_ACTIVE");
+ if (cDxf) zip.file("cladiri.dxf", cDxf);
+ } catch {
+ // DXF conversion not available — skip silently
+ }
+
// ── Comprehensive quality analysis ──
const withGeomRecords = dbTerenuri.filter(
(r) =>
@@ -685,6 +698,15 @@ export async function POST(req: Request) {
if (validated.mode === "magic" && magicGpkg && csvContent) {
zip.file("terenuri_magic.gpkg", magicGpkg);
+ try {
+ const { gpkgToDxf } = await import(
+ "@/modules/parcel-sync/services/gpkg-export"
+ );
+ const mDxf = await gpkgToDxf(magicGpkg, "TERENURI_MAGIC");
+ if (mDxf) zip.file("terenuri_magic.dxf", mDxf);
+ } catch {
+ // DXF conversion not available
+ }
zip.file("terenuri_complet.csv", csvContent);
report.magic = {
csvRows: csvContent.split("\n").length - 1,
diff --git a/src/app/api/eterra/export-local/route.ts b/src/app/api/eterra/export-local/route.ts
index 187bd50..c8757cb 100644
--- a/src/app/api/eterra/export-local/route.ts
+++ b/src/app/api/eterra/export-local/route.ts
@@ -182,6 +182,15 @@ async function buildFullZip(siruta: string, mode: "base" | "magic") {
zip.file("terenuri.gpkg", terenuriGpkg);
zip.file("cladiri.gpkg", cladiriGpkg);
+ // DXF versions (non-fatal — ogr2ogr may not be available)
+ const { gpkgToDxf } = await import(
+ "@/modules/parcel-sync/services/gpkg-export"
+ );
+ const terenuriDxf = await gpkgToDxf(terenuriGpkg, "TERENURI_ACTIVE");
+ if (terenuriDxf) zip.file("terenuri.dxf", terenuriDxf);
+ const cladiriDxf = await gpkgToDxf(cladiriGpkg, "CLADIRI_ACTIVE");
+ if (cladiriDxf) zip.file("cladiri.dxf", cladiriDxf);
+
if (mode === "magic") {
// ── Magic: enrichment-merged GPKG + CSV + quality report ──
const headers = [
@@ -295,6 +304,8 @@ async function buildFullZip(siruta: string, mode: "base" | "magic") {
});
zip.file("terenuri_magic.gpkg", magicGpkg);
+ const magicDxf = await gpkgToDxf(magicGpkg, "TERENURI_MAGIC");
+ if (magicDxf) zip.file("terenuri_magic.dxf", magicDxf);
zip.file("terenuri_complet.csv", csvRows.join("\n"));
// ── Quality analysis ──
diff --git a/src/modules/parcel-sync/components/tabs/export-tab.tsx b/src/modules/parcel-sync/components/tabs/export-tab.tsx
index 7cb6304..179cee0 100644
--- a/src/modules/parcel-sync/components/tabs/export-tab.tsx
+++ b/src/modules/parcel-sync/components/tabs/export-tab.tsx
@@ -680,65 +680,97 @@ export function ExportTab({
{/* Hero buttons */}
{sirutaValid && (session.connected || canExportLocal) ? (
-
-
+ {(() => {
+ // Build tooltip with layer details for hero buttons
+ const layerLines = dbLayersSummary
+ .filter((l) => l.count > 0)
+ .sort((a, b) => b.count - a.count)
+ .map(
+ (l) =>
+ `${l.label}: ${l.count.toLocaleString("ro")} entitati${l.lastSynced ? ` (sync ${relativeTime(l.lastSynced)})` : ""}`,
+ );
+ const enriched = dbLayersSummary.reduce(
+ (sum, l) => {
+ const enrichCount =
+ syncRuns.find(
+ (r) => r.layerId === l.id && r.status === "done",
+ )?.totalLocal ?? 0;
+ return sum + enrichCount;
+ },
+ 0,
+ );
+ const baseTooltip = layerLines.length > 0
+ ? `ZIP contine:\n• ${layerLines.join("\n• ")}\n\nFormate: GPKG + DXF per layer`
+ : "Nicio data in DB";
+ const magicTooltip = layerLines.length > 0
+ ? `ZIP contine:\n• ${layerLines.join("\n• ")}\n\nFormate: GPKG + DXF + CSV complet\n+ Raport calitate enrichment`
+ : "Nicio data in DB";
-