diff --git a/src/modules/word-xml/components/word-xml-module.tsx b/src/modules/word-xml/components/word-xml-module.tsx
index ad1eac1..479f13f 100644
--- a/src/modules/word-xml/components/word-xml-module.tsx
+++ b/src/modules/word-xml/components/word-xml-module.tsx
@@ -1,18 +1,25 @@
-'use client';
+"use client";
-import { useXmlConfig } from '../hooks/use-xml-config';
-import { XmlSettings } from './xml-settings';
-import { CategoryManager } from './category-manager';
-import { XmlPreview } from './xml-preview';
-import { Separator } from '@/shared/components/ui/separator';
-import { Button } from '@/shared/components/ui/button';
-import { RotateCcw } from 'lucide-react';
+import { useXmlConfig } from "../hooks/use-xml-config";
+import { XmlSettings } from "./xml-settings";
+import { CategoryManager } from "./category-manager";
+import { XmlPreview } from "./xml-preview";
+import { Separator } from "@/shared/components/ui/separator";
+import { Button } from "@/shared/components/ui/button";
+import { RotateCcw } from "lucide-react";
export function WordXmlModule() {
const {
- config, setMode, setBaseNamespace, setComputeMetrics,
- setCurrentCategory, updateCategoryFields, addCategory,
- removeCategory, resetCategoryToPreset, clearCategoryFields, resetAll,
+ config,
+ setMode,
+ setBaseNamespace,
+ setCurrentCategory,
+ updateCategoryFields,
+ addCategory,
+ removeCategory,
+ resetCategoryToPreset,
+ clearCategoryFields,
+ resetAll,
} = useXmlConfig();
return (
@@ -21,10 +28,8 @@ export function WordXmlModule() {
diff --git a/src/modules/word-xml/components/xml-preview.tsx b/src/modules/word-xml/components/xml-preview.tsx
index a46ac5b..0c34908 100644
--- a/src/modules/word-xml/components/xml-preview.tsx
+++ b/src/modules/word-xml/components/xml-preview.tsx
@@ -1,28 +1,37 @@
-'use client';
+"use client";
-import { useMemo, useState } from 'react';
-import { Copy, Download, FileArchive } from 'lucide-react';
-import { Button } from '@/shared/components/ui/button';
-import type { XmlGeneratorConfig } from '../types';
-import { generateAllCategories, downloadXmlFile, downloadZipAll } from '../services/xml-generator';
+import { useMemo, useState } from "react";
+import { Copy, Download, FileArchive } from "lucide-react";
+import { Button } from "@/shared/components/ui/button";
+import type { XmlGeneratorConfig } from "../types";
+import {
+ generateAllCategories,
+ downloadXmlFile,
+ downloadZipAll,
+} from "../services/xml-generator";
interface XmlPreviewProps {
config: XmlGeneratorConfig;
}
export function XmlPreview({ config }: XmlPreviewProps) {
- const [copied, setCopied] = useState<'xml' | 'xpath' | null>(null);
+ const [copied, setCopied] = useState<"xml" | "xpath" | null>(null);
const allOutputs = useMemo(
- () => generateAllCategories(config.categories, config.baseNamespace, config.mode, config.computeMetrics),
- [config.categories, config.baseNamespace, config.mode, config.computeMetrics],
+ () =>
+ generateAllCategories(
+ config.categories,
+ config.baseNamespace,
+ config.mode,
+ ),
+ [config.categories, config.baseNamespace, config.mode],
);
const current = allOutputs[config.currentCategory];
- const xml = current?.xml || '';
- const xpaths = current?.xpaths || '';
+ const xml = current?.xml || "";
+ const xpaths = current?.xpaths || "";
- const handleCopy = async (text: string, type: 'xml' | 'xpath') => {
+ const handleCopy = async (text: string, type: "xml" | "xpath") => {
try {
await navigator.clipboard.writeText(text);
setCopied(type);
@@ -32,9 +41,9 @@ export function XmlPreview({ config }: XmlPreviewProps) {
}
};
- const safeCatName = (config.currentCategory || 'unknown')
- .replace(/\s+/g, '_')
- .replace(/[^A-Za-z0-9_.-]/g, '');
+ const safeCatName = (config.currentCategory || "unknown")
+ .replace(/\s+/g, "_")
+ .replace(/[^A-Za-z0-9_.-]/g, "");
const handleDownloadCurrent = () => {
if (!xml) return;
@@ -42,7 +51,7 @@ export function XmlPreview({ config }: XmlPreviewProps) {
};
const handleDownloadZip = async () => {
- await downloadZipAll(config.categories, config.baseNamespace, config.mode, config.computeMetrics);
+ await downloadZipAll(config.categories, config.baseNamespace, config.mode);
};
return (
@@ -50,7 +59,12 @@ export function XmlPreview({ config }: XmlPreviewProps) {
Preview & Export
-
diff --git a/src/modules/word-xml/components/xml-settings.tsx b/src/modules/word-xml/components/xml-settings.tsx
index a738cf7..faf41e7 100644
--- a/src/modules/word-xml/components/xml-settings.tsx
+++ b/src/modules/word-xml/components/xml-settings.tsx
@@ -1,23 +1,22 @@
-'use client';
+"use client";
-import type { XmlGeneratorMode } from '../types';
-import { Input } from '@/shared/components/ui/input';
-import { Label } from '@/shared/components/ui/label';
-import { Switch } from '@/shared/components/ui/switch';
-import { cn } from '@/shared/lib/utils';
+import type { XmlGeneratorMode } from "../types";
+import { Input } from "@/shared/components/ui/input";
+import { Label } from "@/shared/components/ui/label";
+import { cn } from "@/shared/lib/utils";
interface XmlSettingsProps {
baseNamespace: string;
mode: XmlGeneratorMode;
- computeMetrics: boolean;
onSetBaseNamespace: (ns: string) => void;
onSetMode: (mode: XmlGeneratorMode) => void;
- onSetComputeMetrics: (v: boolean) => void;
}
export function XmlSettings({
- baseNamespace, mode, computeMetrics,
- onSetBaseNamespace, onSetMode, onSetComputeMetrics,
+ baseNamespace,
+ mode,
+ onSetBaseNamespace,
+ onSetMode,
}: XmlSettingsProps) {
return (
@@ -38,31 +37,28 @@ export function XmlSettings({
- {(['simple', 'advanced'] as XmlGeneratorMode[]).map((m) => (
+ {(["simple", "advanced"] as XmlGeneratorMode[]).map((m) => (
onSetMode(m)}
className={cn(
- 'rounded-full border px-3 py-1 text-xs font-medium transition-colors',
+ "rounded-full border px-3 py-1 text-xs font-medium transition-colors",
mode === m
- ? 'border-primary bg-primary text-primary-foreground'
- : 'border-border hover:bg-accent'
+ ? "border-primary bg-primary text-primary-foreground"
+ : "border-border hover:bg-accent",
)}
>
- {m === 'simple' ? 'Simple' : 'Advanced'}
+ {m === "simple" ? "Simple" : "Advanced"}
))}
- {mode === 'simple' ? 'Doar câmpurile definite.' : '+ Short / Upper / Lower / Initials / First.'}
+ {mode === "simple"
+ ? "Doar câmpurile definite."
+ : "+ Short / Upper / Lower / Initials / First."}
-
-
-
-
-
);
diff --git a/src/modules/word-xml/hooks/use-xml-config.ts b/src/modules/word-xml/hooks/use-xml-config.ts
index dfede80..2487d84 100644
--- a/src/modules/word-xml/hooks/use-xml-config.ts
+++ b/src/modules/word-xml/hooks/use-xml-config.ts
@@ -1,20 +1,19 @@
-'use client';
+"use client";
-import { useState, useCallback, useMemo } from 'react';
-import type { XmlGeneratorConfig, XmlGeneratorMode } from '../types';
-import { DEFAULT_PRESETS } from '../services/category-presets';
+import { useState, useCallback, useMemo } from "react";
+import type { XmlGeneratorConfig, XmlGeneratorMode } from "../types";
+import { DEFAULT_PRESETS } from "../services/category-presets";
function createDefaultConfig(): XmlGeneratorConfig {
const categories: Record = {};
for (const [name, fields] of Object.entries(DEFAULT_PRESETS)) {
- categories[name] = { name, fieldsText: fields.join('\n') };
+ categories[name] = { name, fieldsText: fields.join("\n") };
}
return {
- baseNamespace: 'http://schemas.beletage.ro/contract',
- mode: 'advanced',
- computeMetrics: true,
+ baseNamespace: "http://schemas.beletage.ro/contract",
+ mode: "advanced",
categories,
- currentCategory: 'Beneficiar',
+ currentCategory: "Beneficiar",
};
}
@@ -29,34 +28,33 @@ export function useXmlConfig() {
setConfig((prev) => ({ ...prev, baseNamespace }));
}, []);
- const setComputeMetrics = useCallback((computeMetrics: boolean) => {
- setConfig((prev) => ({ ...prev, computeMetrics }));
- }, []);
-
const setCurrentCategory = useCallback((name: string) => {
setConfig((prev) => ({ ...prev, currentCategory: name }));
}, []);
- const updateCategoryFields = useCallback((categoryName: string, fieldsText: string) => {
- setConfig((prev) => {
- const existing = prev.categories[categoryName];
- if (!existing) return prev;
- return {
- ...prev,
- categories: {
- ...prev.categories,
- [categoryName]: { name: existing.name, fieldsText },
- },
- };
- });
- }, []);
+ const updateCategoryFields = useCallback(
+ (categoryName: string, fieldsText: string) => {
+ setConfig((prev) => {
+ const existing = prev.categories[categoryName];
+ if (!existing) return prev;
+ return {
+ ...prev,
+ categories: {
+ ...prev.categories,
+ [categoryName]: { name: existing.name, fieldsText },
+ },
+ };
+ });
+ },
+ [],
+ );
const addCategory = useCallback((name: string) => {
setConfig((prev) => {
if (prev.categories[name]) return prev;
return {
...prev,
- categories: { ...prev.categories, [name]: { name, fieldsText: '' } },
+ categories: { ...prev.categories, [name]: { name, fieldsText: "" } },
currentCategory: name,
};
});
@@ -70,7 +68,9 @@ export function useXmlConfig() {
return {
...prev,
categories: next,
- currentCategory: keys.includes(prev.currentCategory) ? prev.currentCategory : keys[0] || '',
+ currentCategory: keys.includes(prev.currentCategory)
+ ? prev.currentCategory
+ : keys[0] || "",
};
});
}, []);
@@ -82,7 +82,7 @@ export function useXmlConfig() {
...prev,
categories: {
...prev.categories,
- [name]: { name, fieldsText: preset.join('\n') },
+ [name]: { name, fieldsText: preset.join("\n") },
},
}));
}, []);
@@ -95,7 +95,7 @@ export function useXmlConfig() {
...prev,
categories: {
...prev.categories,
- [name]: { name: existing.name, fieldsText: '' },
+ [name]: { name: existing.name, fieldsText: "" },
},
};
});
@@ -109,20 +109,32 @@ export function useXmlConfig() {
setConfig(loaded);
}, []);
- return useMemo(() => ({
- config,
- setMode,
- setBaseNamespace,
- setComputeMetrics,
- setCurrentCategory,
- updateCategoryFields,
- addCategory,
- removeCategory,
- resetCategoryToPreset,
- clearCategoryFields,
- resetAll,
- loadConfig,
- }), [config, setMode, setBaseNamespace, setComputeMetrics, setCurrentCategory,
- updateCategoryFields, addCategory, removeCategory, resetCategoryToPreset,
- clearCategoryFields, resetAll, loadConfig]);
+ return useMemo(
+ () => ({
+ config,
+ setMode,
+ setBaseNamespace,
+ setCurrentCategory,
+ updateCategoryFields,
+ addCategory,
+ removeCategory,
+ resetCategoryToPreset,
+ clearCategoryFields,
+ resetAll,
+ loadConfig,
+ }),
+ [
+ config,
+ setMode,
+ setBaseNamespace,
+ setCurrentCategory,
+ updateCategoryFields,
+ addCategory,
+ removeCategory,
+ resetCategoryToPreset,
+ clearCategoryFields,
+ resetAll,
+ loadConfig,
+ ],
+ );
}
diff --git a/src/modules/word-xml/services/xml-generator.ts b/src/modules/word-xml/services/xml-generator.ts
index 260d2c6..00d8014 100644
--- a/src/modules/word-xml/services/xml-generator.ts
+++ b/src/modules/word-xml/services/xml-generator.ts
@@ -1,21 +1,21 @@
-import type { XmlGeneratorMode, XmlCategory, GeneratedOutput } from '../types';
+import type { XmlGeneratorMode, XmlCategory, GeneratedOutput } from "../types";
function sanitizeName(name: string): string | null {
const trimmed = name.trim();
if (!trimmed) return null;
- let n = trimmed.replace(/\s+/g, '_').replace(/[^A-Za-z0-9_.-]/g, '');
- if (!/^[A-Za-z_]/.test(n)) n = '_' + n;
+ let n = trimmed.replace(/\s+/g, "_").replace(/[^A-Za-z0-9_.-]/g, "");
+ if (!/^[A-Za-z_]/.test(n)) n = "_" + n;
return n || null;
}
function getCategoryNamespace(baseNs: string, category: string): string {
const safeCat = sanitizeName(category) || category;
- return baseNs.replace(/\/+$/, '') + '/' + safeCat;
+ return baseNs.replace(/\/+$/, "") + "/" + safeCat;
}
function getCategoryRoot(category: string): string {
const safeCat = sanitizeName(category) || category;
- return safeCat + 'Data';
+ return safeCat + "Data";
}
interface FieldEntry {
@@ -29,14 +29,13 @@ export function generateCategoryXml(
catData: XmlCategory,
baseNamespace: string,
mode: XmlGeneratorMode,
- computeMetrics: boolean,
): GeneratedOutput {
const raw = catData.fieldsText
.split(/\r?\n/)
.map((l) => l.trim())
.filter((l) => l.length > 0);
- if (raw.length === 0) return { xml: '', xpaths: '' };
+ if (raw.length === 0) return { xml: "", xpaths: "" };
const ns = getCategoryNamespace(baseNamespace, category);
const root = getCategoryRoot(category);
@@ -51,19 +50,19 @@ export function generateCategoryXml(
let baseName = base;
let idx = 2;
while (usedNames.has(baseName)) {
- baseName = base + '_' + idx;
+ baseName = base + "_" + idx;
idx++;
}
usedNames.add(baseName);
const variants = [baseName];
- if (mode === 'advanced') {
- const suffixes = ['Short', 'Upper', 'Lower', 'Initials', 'First'];
+ if (mode === "advanced") {
+ const suffixes = ["Short", "Upper", "Lower", "Initials", "First"];
for (const suffix of suffixes) {
let vn = baseName + suffix;
let k = 2;
while (usedNames.has(vn)) {
- vn = baseName + suffix + '_' + k;
+ vn = baseName + suffix + "_" + k;
k++;
}
usedNames.add(vn);
@@ -74,24 +73,7 @@ export function generateCategoryXml(
fields.push({ label, baseName, variants });
}
- // Auto-add POT/CUT for Suprafete category
- const extraMetricFields: FieldEntry[] = [];
- if (computeMetrics && category.toLowerCase().includes('suprafete')) {
- const hasTeren = fields.some((f) => f.baseName.toLowerCase().includes('suprafatateren'));
- const hasLaSol = fields.some((f) => f.baseName.toLowerCase().includes('suprafataconstruitalasol'));
- const hasDesf = fields.some((f) => f.baseName.toLowerCase().includes('suprafatadesfasurata'));
-
- if (hasTeren && hasLaSol && !usedNames.has('POT')) {
- usedNames.add('POT');
- extraMetricFields.push({ label: 'Procent Ocupare Teren', baseName: 'POT', variants: ['POT'] });
- }
- if (hasTeren && hasDesf && !usedNames.has('CUT')) {
- usedNames.add('CUT');
- extraMetricFields.push({ label: 'Coeficient Utilizare Teren', baseName: 'CUT', variants: ['CUT'] });
- }
- }
-
- const allFields = fields.concat(extraMetricFields);
+ const allFields = fields;
// Build XML
let xml = '\n';
@@ -110,18 +92,8 @@ export function generateCategoryXml(
for (const v of f.variants) {
xp += `/${root}/${v}\n`;
}
- xp += '\n';
+ xp += "\n";
}
- if (extraMetricFields.length > 0) {
- xp += '# Metrici auto (POT / CUT)\n';
- for (const f of extraMetricFields) {
- for (const v of f.variants) {
- xp += `/${root}/${v}\n`;
- }
- }
- xp += '\n';
- }
-
return { xml, xpaths: xp };
}
@@ -129,20 +101,19 @@ export function generateAllCategories(
categories: Record,
baseNamespace: string,
mode: XmlGeneratorMode,
- computeMetrics: boolean,
): Record {
const results: Record = {};
for (const cat of Object.keys(categories)) {
const catData = categories[cat];
if (!catData) continue;
- results[cat] = generateCategoryXml(cat, catData, baseNamespace, mode, computeMetrics);
+ results[cat] = generateCategoryXml(cat, catData, baseNamespace, mode);
}
return results;
}
export function downloadXmlFile(xml: string, filename: string): void {
- const blob = new Blob([xml], { type: 'application/xml' });
- const a = document.createElement('a');
+ const blob = new Blob([xml], { type: "application/xml" });
+ const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = filename;
document.body.appendChild(a);
@@ -155,13 +126,12 @@ export async function downloadZipAll(
categories: Record,
baseNamespace: string,
mode: XmlGeneratorMode,
- computeMetrics: boolean,
): Promise {
- const JSZip = (await import('jszip')).default;
- const results = generateAllCategories(categories, baseNamespace, mode, computeMetrics);
+ const JSZip = (await import("jszip")).default;
+ const results = generateAllCategories(categories, baseNamespace, mode);
const zip = new JSZip();
- const folder = zip.folder('customXmlParts')!;
+ const folder = zip.folder("customXmlParts")!;
let hasAny = false;
for (const cat of Object.keys(results)) {
@@ -175,10 +145,10 @@ export async function downloadZipAll(
if (!hasAny) return;
- const content = await zip.generateAsync({ type: 'blob' });
- const a = document.createElement('a');
+ const content = await zip.generateAsync({ type: "blob" });
+ const a = document.createElement("a");
a.href = URL.createObjectURL(content);
- a.download = 'beletage_custom_xml_parts.zip';
+ a.download = "beletage_custom_xml_parts.zip";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
diff --git a/src/modules/word-xml/types.ts b/src/modules/word-xml/types.ts
index 1a6f6ed..dff3be7 100644
--- a/src/modules/word-xml/types.ts
+++ b/src/modules/word-xml/types.ts
@@ -1,4 +1,4 @@
-export type XmlGeneratorMode = 'simple' | 'advanced';
+export type XmlGeneratorMode = "simple" | "advanced";
export interface XmlCategory {
name: string;
@@ -8,7 +8,6 @@ export interface XmlCategory {
export interface XmlGeneratorConfig {
baseNamespace: string;
mode: XmlGeneratorMode;
- computeMetrics: boolean;
categories: Record;
currentCategory: string;
}