Initial commit: ArchiTools modular dashboard platform
Complete Next.js 16 application with 13 fully implemented modules: Email Signature, Word XML Generator, Registratura, Dashboard, Tag Manager, IT Inventory, Address Book, Password Vault, Mini Utilities, Prompt Generator, Digital Signatures, Word Templates, and AI Chat. Includes core platform systems (module registry, feature flags, storage abstraction, i18n, theming, auth stub, tagging), 16 technical documentation files, Docker deployment config, and legacy HTML tool reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
620
docs/guides/HTML-TOOL-INTEGRATION.md
Normal file
620
docs/guides/HTML-TOOL-INTEGRATION.md
Normal file
@@ -0,0 +1,620 @@
|
||||
# HTML Tool Integration Guide
|
||||
|
||||
How to migrate existing standalone HTML tools into React modules within the ArchiTools dashboard.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
ArchiTools currently has four standalone HTML files that implement useful internal tools:
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `emailsignature/emailsignature-config.html` | Email signature configurator with live preview, color pickers, layout sliders, HTML export |
|
||||
| `wordXMLgenerator/word-xml-generator-basic.html` | Simple Word XML Custom Part generator |
|
||||
| `wordXMLgenerator/word-xml-generator-medium.html` | Extended version with Short/Upper/Lower/Initials/First field variants |
|
||||
| `wordXMLgenerator/word-xml-generator-advanced.html` | Full version with categories, localStorage, simple/advanced mode, POT/CUT metrics, ZIP export |
|
||||
|
||||
### Why Integrate
|
||||
|
||||
Standalone HTML files work, but they cannot:
|
||||
|
||||
- Share a consistent UI theme (dark/light toggle, company branding).
|
||||
- Use shared storage abstraction (configurations saved in one tool are invisible to another).
|
||||
- Participate in feature flags or access control.
|
||||
- Link to related data (e.g., an XML template referencing a project tag).
|
||||
- Provide a unified navigation experience.
|
||||
- Be tested with standard tooling (Jest, Playwright).
|
||||
|
||||
Integration brings these tools into the dashboard shell with shared infrastructure while preserving all existing functionality.
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
Migration happens in three phases. Each phase produces a working state -- there is no "big bang" cutover.
|
||||
|
||||
### Phase 1: Embed (Temporary Bridge)
|
||||
|
||||
Wrap the existing HTML file in an `<iframe>` inside a dashboard page. This gives immediate navigation integration with zero rewrite.
|
||||
|
||||
```tsx
|
||||
// src/modules/email-signature/pages/email-signature-page.tsx (Phase 1 only)
|
||||
|
||||
export function EmailSignaturePage() {
|
||||
return (
|
||||
<div className="h-[calc(100vh-3.5rem)]">
|
||||
<iframe
|
||||
src="/legacy/emailsignature-config.html"
|
||||
className="w-full h-full border-0"
|
||||
title="Email Signature Configurator"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**When to use Phase 1:**
|
||||
- When a tool needs to appear in the sidebar immediately but rewrite resources are not available.
|
||||
- As a fallback during Phase 2 development (iframe stays live while React version is being built).
|
||||
|
||||
**Limitations:**
|
||||
- No theme synchronization (iframe has its own styles).
|
||||
- No shared state between iframe and parent.
|
||||
- No storage abstraction.
|
||||
- Content Security Policy may block certain CDN scripts.
|
||||
|
||||
**Phase 1 is not recommended as a long-term solution.** Move to Phase 2 as soon as practical.
|
||||
|
||||
### Phase 2: Extract
|
||||
|
||||
Pull JavaScript logic out of the HTML files into typed TypeScript hooks and utility functions. Build a React UI that replaces the HTML structure.
|
||||
|
||||
This is where the bulk of the work happens. The goal is functional parity with the original tool, running inside the React component tree with proper state management.
|
||||
|
||||
Detailed extraction plans for each tool are in the sections below.
|
||||
|
||||
### Phase 3: Normalize
|
||||
|
||||
With React UI in place, integrate with platform-level features:
|
||||
|
||||
- **Storage abstraction**: Save/load configurations through the shared storage layer instead of raw `localStorage`.
|
||||
- **Theming**: All colors respond to dark/light toggle and company accent.
|
||||
- **Tagging**: Link generated artifacts to project tags from the tag manager.
|
||||
- **Feature flags**: Gate experimental features behind flags.
|
||||
- **Company context**: Tool behavior adapts to the selected company (logo, colors, address, namespace).
|
||||
- **Cross-module linking**: An XML template can reference a project; a signature config can link to a company profile.
|
||||
|
||||
---
|
||||
|
||||
## Email Signature Generator -- Migration Plan
|
||||
|
||||
### Current State Analysis
|
||||
|
||||
The existing `emailsignature-config.html` contains:
|
||||
|
||||
1. **Data inputs**: prefix, name, title, phone (4 text fields).
|
||||
2. **Color picker system**: 7 color targets (prefix, name, title, address, phone, website, motto) with 4 swatch options each (Beletage brand palette).
|
||||
3. **Layout sliders**: 8 range inputs controlling pixel-level spacing (green line width, section spacing, logo spacing, title spacing, gutter alignment, icon-text spacing, icon vertical position, motto spacing).
|
||||
4. **Options**: 3 checkboxes (reply variant, super-reply variant, SVG images).
|
||||
5. **Signature HTML template builder**: `generateSignatureHTML(data)` function producing a table-based email signature.
|
||||
6. **Phone formatter**: Converts `07xxxxxxxx` to `+40 xxx xxx xxx` format.
|
||||
7. **Live preview**: Real-time DOM update on any input change.
|
||||
8. **Export**: Downloads the signature HTML as a file.
|
||||
9. **Zoom toggle**: 100%/200% preview scaling.
|
||||
10. **Collapsible sections**: Manual accordion implementation.
|
||||
|
||||
Everything is Beletage-specific: logo URL, address, website, motto, brand colors.
|
||||
|
||||
### Extraction Plan
|
||||
|
||||
#### Hook: `useSignatureBuilder`
|
||||
|
||||
Encapsulates the signature generation logic.
|
||||
|
||||
```
|
||||
Source: generateSignatureHTML() function (lines 280-361)
|
||||
Target: src/modules/email-signature/hooks/use-signature-builder.ts
|
||||
|
||||
Responsibilities:
|
||||
- Accept SignatureConfig object (all field values, colors, spacing, variant flags)
|
||||
- Return generated HTML string
|
||||
- Return structured SignatureData for preview rendering
|
||||
- Pure computation, no side effects
|
||||
|
||||
Interface:
|
||||
Input: SignatureConfig (typed object with all config fields)
|
||||
Output: { html: string; previewData: SignatureData }
|
||||
```
|
||||
|
||||
#### Hook: `useSignatureExport`
|
||||
|
||||
Handles file download and clipboard copy.
|
||||
|
||||
```
|
||||
Source: export button click handler (lines 441-450)
|
||||
Target: src/modules/email-signature/hooks/use-signature-export.ts
|
||||
|
||||
Responsibilities:
|
||||
- Generate Blob from HTML string
|
||||
- Trigger file download with appropriate filename
|
||||
- Copy HTML to clipboard
|
||||
- Filename includes company name and date
|
||||
|
||||
Interface:
|
||||
Input: { html: string; companySlug: string }
|
||||
Output: { downloadHtml: () => void; copyToClipboard: () => Promise<void> }
|
||||
```
|
||||
|
||||
#### Utility: `formatPhoneNumber`
|
||||
|
||||
```
|
||||
Source: phone formatting logic in updatePreview() (lines 365-372)
|
||||
Target: src/shared/utils/format-phone.ts
|
||||
|
||||
Responsibilities:
|
||||
- Accept raw phone string
|
||||
- Detect Romanian mobile format (07xxxxxxxx)
|
||||
- Return { display: string; tel: string } with formatted display and tel: link
|
||||
|
||||
This is a shared utility, not signature-specific.
|
||||
```
|
||||
|
||||
#### React UI Replacements
|
||||
|
||||
| Original | React Replacement |
|
||||
|---|---|
|
||||
| Text inputs with `document.getElementById` | Controlled `<Input>` components with React state |
|
||||
| Color swatch grid with DOM event delegation | `<ColorPicker>` component with `useState` |
|
||||
| Range inputs with manual value display | `<Slider>` (shadcn/ui) with value label |
|
||||
| Collapsible sections | `<Collapsible>` (shadcn/ui) |
|
||||
| Checkboxes | `<Switch>` or `<Checkbox>` (shadcn/ui) |
|
||||
| Live preview via `innerHTML` | React component rendering signature structure |
|
||||
| `alert()`/`confirm()` | `<AlertDialog>` (shadcn/ui) |
|
||||
| File download via DOM | `useSignatureExport` hook |
|
||||
|
||||
#### Generalization: Multi-Company Support
|
||||
|
||||
The current tool is hardcoded for Beletage. The React version must support all three companies.
|
||||
|
||||
```ts
|
||||
// src/config/companies.ts
|
||||
|
||||
export interface CompanyProfile {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
accent: string; // hex color
|
||||
logo: {
|
||||
png: string;
|
||||
svg: string;
|
||||
};
|
||||
address: {
|
||||
street: string;
|
||||
city: string;
|
||||
county: string;
|
||||
postalCode: string;
|
||||
country: string;
|
||||
mapsUrl: string;
|
||||
};
|
||||
website: string;
|
||||
motto: string;
|
||||
brandColors: Record<string, string>; // named palette
|
||||
signatureIcons: {
|
||||
greySlash: { png: string; svg: string };
|
||||
greenSlash: { png: string; svg: string };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The company selector in the header drives `CompanyProfile` into context. The signature builder reads from this context to populate logo, address, website, motto, and available colors.
|
||||
|
||||
#### New: Storage Integration
|
||||
|
||||
Save and load signature configurations via the storage abstraction:
|
||||
|
||||
```ts
|
||||
// Signature configs are stored as:
|
||||
{
|
||||
id: string;
|
||||
companyId: string;
|
||||
name: string; // e.g., "Marius TARAU - Beletage"
|
||||
config: SignatureConfig; // all field values
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
Users can save multiple configs (one per person/company combo), load previous configs, and delete old ones.
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
src/modules/email-signature/
|
||||
pages/
|
||||
email-signature-page.tsx -- Main page component
|
||||
components/
|
||||
signature-form.tsx -- Config form (inputs, colors, sliders)
|
||||
signature-preview.tsx -- Live preview panel
|
||||
signature-color-picker.tsx -- Color swatch selector
|
||||
saved-configs-list.tsx -- List of saved configurations
|
||||
hooks/
|
||||
use-signature-builder.ts -- HTML generation logic
|
||||
use-signature-export.ts -- Download/copy logic
|
||||
use-signature-config.ts -- State management for all config fields
|
||||
types.ts -- SignatureConfig, SignatureData interfaces
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Word XML Generators -- Migration Plan (Consolidate 3 into 1)
|
||||
|
||||
### Current State Analysis
|
||||
|
||||
Three separate HTML files with increasing complexity:
|
||||
|
||||
**Basic** (`word-xml-generator-basic.html`):
|
||||
- Namespace URI, root element name, field list (textarea).
|
||||
- Generates XML with one element per field.
|
||||
- Generates XPath list.
|
||||
- Copy to clipboard, download XML, demo fill.
|
||||
- Field name sanitization (spaces to underscores, invalid chars removed, dedup).
|
||||
|
||||
**Medium** (`word-xml-generator-medium.html`):
|
||||
- Same as basic, but generates 6 variants per field: base, Short, Upper, Lower, Initials, First.
|
||||
- `initials()` helper function.
|
||||
|
||||
**Advanced** (`word-xml-generator-advanced.html`):
|
||||
- Category-based organization (Beneficiar, Proiect, Suprafete, Meta) with default presets.
|
||||
- Per-category namespace (base namespace + `/CategoryName`).
|
||||
- Per-category root element (`CategoryNameData`).
|
||||
- Simple/Advanced mode toggle (advanced adds the 6 variants).
|
||||
- POT/CUT metric computation for "Suprafete" category.
|
||||
- localStorage persistence for category data.
|
||||
- Category management (add, delete, reset to preset, clear).
|
||||
- Single-category XML download.
|
||||
- ZIP export of all categories via JSZip.
|
||||
- Pill-based category selector UI.
|
||||
|
||||
### Consolidation Strategy
|
||||
|
||||
The three tools become a single React module with a complexity toggle:
|
||||
|
||||
| Mode | Equivalent to | Behavior |
|
||||
|---|---|---|
|
||||
| **Simplu** | basic | One element per field, no variants |
|
||||
| **Avansat** | advanced | Categories, variants, POT/CUT, ZIP |
|
||||
|
||||
The medium version is subsumed by the advanced mode -- it was an intermediate step, not a distinct use case.
|
||||
|
||||
### Extraction Plan
|
||||
|
||||
#### Hook: `useXmlGenerator`
|
||||
|
||||
Core XML generation logic.
|
||||
|
||||
```
|
||||
Source: generateXML() from basic, generateCategory() from advanced
|
||||
Target: src/modules/xml-generator/hooks/use-xml-generator.ts
|
||||
|
||||
Responsibilities:
|
||||
- Accept field list, namespace, root element name, mode (simple/advanced)
|
||||
- Generate XML string for a Custom XML Part
|
||||
- Generate XPath listing
|
||||
- Handle variant generation (Short, Upper, Lower, Initials, First)
|
||||
- Handle metric fields (POT/CUT) when category is surface-related
|
||||
|
||||
Interface:
|
||||
Input: XmlGeneratorInput { fields: string[]; namespace: string; rootElement: string; mode: 'simple' | 'advanced'; computeMetrics: boolean; categoryName?: string }
|
||||
Output: XmlGeneratorResult { xml: string; xpaths: string; fieldCount: number }
|
||||
```
|
||||
|
||||
#### Hook: `useCategoryManager`
|
||||
|
||||
Category CRUD and persistence.
|
||||
|
||||
```
|
||||
Source: initCategories(), switchCategory(), addCategoryPrompt(), etc. from advanced
|
||||
Target: src/modules/xml-generator/hooks/use-category-manager.ts
|
||||
|
||||
Responsibilities:
|
||||
- Manage list of categories with their field text
|
||||
- Track active category
|
||||
- Provide CRUD operations (add, delete, rename, reset to preset, clear)
|
||||
- Persist to storage abstraction (not raw localStorage)
|
||||
- Load default presets on first use
|
||||
|
||||
Interface:
|
||||
Input: StorageAdapter
|
||||
Output: { categories: Category[]; activeCategory: string; addCategory, deleteCategory, ... }
|
||||
```
|
||||
|
||||
#### Pure Function: `sanitizeXmlName`
|
||||
|
||||
```
|
||||
Source: sanitizeName() / sanitizeXmlName() (present in all three files)
|
||||
Target: src/modules/xml-generator/utils/sanitize-xml-name.ts
|
||||
|
||||
Responsibilities:
|
||||
- Trim whitespace
|
||||
- Replace spaces with underscores
|
||||
- Remove invalid XML name characters
|
||||
- Ensure name starts with letter or underscore
|
||||
- Return null for empty input
|
||||
|
||||
Easily unit-tested in isolation.
|
||||
```
|
||||
|
||||
#### Pure Function: `generateFieldVariants`
|
||||
|
||||
```
|
||||
Source: variant generation logic in medium and advanced
|
||||
Target: src/modules/xml-generator/utils/generate-field-variants.ts
|
||||
|
||||
Responsibilities:
|
||||
- Given a base field name, return array of variant names
|
||||
- Variants: base, baseShort, baseUpper, baseLower, baseInitials, baseFirst
|
||||
- Deduplication against a provided Set of used names
|
||||
```
|
||||
|
||||
#### Pure Function: `generateXpaths`
|
||||
|
||||
```
|
||||
Source: XPath string building in all three files
|
||||
Target: src/modules/xml-generator/utils/generate-xpaths.ts
|
||||
|
||||
Responsibilities:
|
||||
- Given root element and field list (with variants), produce formatted XPath listing
|
||||
- Include namespace and root info in header
|
||||
```
|
||||
|
||||
#### Service: `zipExportService`
|
||||
|
||||
```
|
||||
Source: downloadZipAll() from advanced
|
||||
Target: src/modules/xml-generator/services/zip-export-service.ts
|
||||
|
||||
Responsibilities:
|
||||
- Accept map of { filename: xmlContent }
|
||||
- Use JSZip to create archive
|
||||
- Return Blob for download
|
||||
|
||||
Dependency: jszip (npm package, replaces CDN script tag)
|
||||
```
|
||||
|
||||
### React UI Replacements
|
||||
|
||||
| Original | React Replacement |
|
||||
|---|---|
|
||||
| Textarea for field list | Controlled `<Textarea>` with React state |
|
||||
| Pill-based category selector | `<Tabs>` (shadcn/ui) or custom pill component |
|
||||
| Simple/Advanced pill toggle | `<Tabs>` with two items |
|
||||
| `prompt()` for new category name | `<Dialog>` with `<Input>` |
|
||||
| `confirm()` for deletion | `<AlertDialog>` |
|
||||
| `alert()` for validation | Toast notification (shadcn/ui `sonner`) |
|
||||
| `<pre>` for XML output | `<pre>` with syntax highlighting (optional) + copy button |
|
||||
| Direct `localStorage` | Storage abstraction via hook |
|
||||
| JSZip CDN | `jszip` npm package |
|
||||
|
||||
### New Features in React Version
|
||||
|
||||
1. **Template presets per company**: Each company can have its own default categories and fields. Driven by company context.
|
||||
2. **Save/load configurations**: Named configurations stored via storage abstraction. Users can maintain multiple XML schemas.
|
||||
3. **Project tag linking**: When generating XML for a specific project, link the configuration to a project tag from the tag manager.
|
||||
4. **Copy individual XPaths**: Click-to-copy on each XPath line, not just the whole block.
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
src/modules/xml-generator/
|
||||
pages/
|
||||
xml-generator-page.tsx -- Main page component
|
||||
components/
|
||||
xml-generator-form.tsx -- Namespace, root, mode controls
|
||||
category-manager.tsx -- Category tabs/pills + CRUD
|
||||
field-editor.tsx -- Textarea for field list
|
||||
xml-preview.tsx -- XML output with copy/download
|
||||
xpath-preview.tsx -- XPath output with copy
|
||||
saved-configs-list.tsx -- Saved configuration browser
|
||||
hooks/
|
||||
use-xml-generator.ts -- XML generation logic
|
||||
use-category-manager.ts -- Category state management
|
||||
use-xml-export.ts -- Download/ZIP export
|
||||
services/
|
||||
zip-export-service.ts -- JSZip wrapper
|
||||
utils/
|
||||
sanitize-xml-name.ts -- Field name sanitization
|
||||
generate-field-variants.ts -- Variant name generation
|
||||
generate-xpaths.ts -- XPath string builder
|
||||
data/
|
||||
default-presets.ts -- Default category presets
|
||||
types.ts -- Category, XmlGeneratorInput, etc.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## General Extraction Patterns
|
||||
|
||||
### DOM Manipulation to React State
|
||||
|
||||
| HTML/JS Pattern | React Equivalent |
|
||||
|---|---|
|
||||
| `document.getElementById('x').value` | `const [x, setX] = useState('')` + controlled input |
|
||||
| `element.innerHTML = html` | JSX return with variables |
|
||||
| `element.textContent = text` | `{text}` in JSX |
|
||||
| `element.classList.toggle('active')` | Conditional className: `cn('pill', isActive && 'active')` |
|
||||
| `element.style.backgroundColor = color` | `style={{ backgroundColor: color }}` or Tailwind class |
|
||||
| `element.addEventListener('input', handler)` | `onChange={handler}` on element |
|
||||
| `document.createElement('div')` | JSX element or `.map()` rendering |
|
||||
| `parent.appendChild(child)` | Render in JSX, controlled by state array |
|
||||
| `element.disabled = true` | `disabled={condition}` prop |
|
||||
|
||||
### Refs
|
||||
|
||||
Use `useRef` only when React state is insufficient:
|
||||
- Measuring DOM element dimensions.
|
||||
- Integrating with third-party DOM libraries.
|
||||
- Storing mutable values that should not trigger re-render.
|
||||
|
||||
Do not use `useRef` as a replacement for `document.getElementById`. That pattern belongs in controlled component state.
|
||||
|
||||
### Storage
|
||||
|
||||
| HTML Pattern | React Equivalent |
|
||||
|---|---|
|
||||
| `localStorage.getItem('key')` | `storageAdapter.get<T>('key')` |
|
||||
| `localStorage.setItem('key', JSON.stringify(data))` | `storageAdapter.set('key', data)` |
|
||||
| `JSON.parse(localStorage.getItem('key'))` | `storageAdapter.get<T>('key')` (typed, handles parse errors) |
|
||||
|
||||
The storage abstraction (`src/core/storage/`) wraps localStorage with:
|
||||
- Typed get/set.
|
||||
- JSON serialization.
|
||||
- Error handling (quota exceeded, parse failures).
|
||||
- Key namespacing by module.
|
||||
- Future: swap backend to IndexedDB or API without changing module code.
|
||||
|
||||
### Styling
|
||||
|
||||
| HTML Pattern | React Equivalent |
|
||||
|---|---|
|
||||
| Inline `style="color: #22B5AB"` | `className="text-teal-500"` or CSS variable |
|
||||
| Tailwind CDN classes | Same Tailwind classes (compiled at build time, not CDN) |
|
||||
| Raw CSS in `<style>` block | Tailwind utilities in JSX, or `globals.css` for truly global styles |
|
||||
| CSS custom properties | Keep if needed for dynamic values (e.g., accent color) |
|
||||
| `linear-gradient(135deg, #38bdf8, #6366f1)` | Tailwind `bg-gradient-to-br from-sky-400 to-indigo-500` or define in theme |
|
||||
|
||||
### Dependencies
|
||||
|
||||
| HTML Pattern | React Equivalent |
|
||||
|---|---|
|
||||
| `<script src="https://cdn.tailwindcss.com">` | Tailwind installed via npm, configured in `tailwind.config.ts` |
|
||||
| `<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/...">` | `npm install jszip` + `import JSZip from 'jszip'` |
|
||||
| Google Fonts CDN link | `next/font/google` in layout |
|
||||
|
||||
### Dialogs
|
||||
|
||||
| HTML Pattern | React Equivalent |
|
||||
|---|---|
|
||||
| `alert('Message')` | `toast('Message')` via sonner, or `<AlertDialog>` for important messages |
|
||||
| `confirm('Are you sure?')` | `<AlertDialog>` with confirm/cancel buttons |
|
||||
| `prompt('Enter name:')` | `<Dialog>` with `<Input>` and submit button |
|
||||
|
||||
---
|
||||
|
||||
## File Placement Conventions
|
||||
|
||||
```
|
||||
src/
|
||||
modules/
|
||||
email-signature/ -- Email signature module
|
||||
pages/ -- Route-level page components
|
||||
components/ -- Module-specific UI components
|
||||
hooks/ -- Module-specific hooks
|
||||
services/ -- Module-specific services (e.g., zip export)
|
||||
utils/ -- Module-specific pure functions
|
||||
data/ -- Static data, presets, defaults
|
||||
types.ts -- Module type definitions
|
||||
xml-generator/ -- XML generator module (consolidated)
|
||||
(same structure)
|
||||
|
||||
shared/
|
||||
components/
|
||||
ui/ -- shadcn/ui components
|
||||
utils/ -- Cross-module utilities (formatPhoneNumber, etc.)
|
||||
hooks/ -- Cross-module hooks
|
||||
|
||||
core/
|
||||
storage/ -- Storage abstraction
|
||||
i18n/
|
||||
labels.ts -- All UI text
|
||||
theme/ -- Theme configuration
|
||||
|
||||
config/
|
||||
companies.ts -- Company profiles
|
||||
modules.ts -- Module registry (drives sidebar)
|
||||
```
|
||||
|
||||
Module code never imports from another module directly. Shared functionality lives in `src/shared/` or `src/core/`.
|
||||
|
||||
---
|
||||
|
||||
## Testing Migrated Logic
|
||||
|
||||
### Unit Tests
|
||||
|
||||
All extracted pure functions and hooks must have unit tests.
|
||||
|
||||
**Pure functions** (sanitize, format, generate): straightforward input/output tests.
|
||||
|
||||
```ts
|
||||
// src/modules/xml-generator/utils/__tests__/sanitize-xml-name.test.ts
|
||||
|
||||
import { sanitizeXmlName } from '../sanitize-xml-name';
|
||||
|
||||
describe('sanitizeXmlName', () => {
|
||||
it('replaces spaces with underscores', () => {
|
||||
expect(sanitizeXmlName('Nume Client')).toBe('Nume_Client');
|
||||
});
|
||||
|
||||
it('removes invalid XML characters', () => {
|
||||
expect(sanitizeXmlName('Preț/m²')).toBe('Prem');
|
||||
});
|
||||
|
||||
it('prepends underscore if starts with digit', () => {
|
||||
expect(sanitizeXmlName('123Field')).toBe('_123Field');
|
||||
});
|
||||
|
||||
it('returns null for empty input', () => {
|
||||
expect(sanitizeXmlName('')).toBeNull();
|
||||
expect(sanitizeXmlName(' ')).toBeNull();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Hooks**: test with `@testing-library/react-hooks` or `renderHook` from `@testing-library/react`.
|
||||
|
||||
```ts
|
||||
import { renderHook, act } from '@testing-library/react';
|
||||
import { useCategoryManager } from '../use-category-manager';
|
||||
|
||||
describe('useCategoryManager', () => {
|
||||
it('initializes with default presets', () => {
|
||||
const { result } = renderHook(() => useCategoryManager(mockStorage));
|
||||
expect(result.current.categories).toHaveLength(4);
|
||||
expect(result.current.activeCategory).toBe('Beneficiar');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
Test full page rendering with mocked storage. Verify that:
|
||||
- Form inputs update preview in real time.
|
||||
- Export produces valid HTML/XML.
|
||||
- Save/load round-trips correctly.
|
||||
|
||||
### Regression Testing
|
||||
|
||||
Before removing Phase 1 iframe, verify the React version produces identical output to the original HTML tool for a set of reference inputs. Store reference outputs as test fixtures.
|
||||
|
||||
For the email signature generator, compare generated HTML string character-by-character for known input configurations.
|
||||
|
||||
---
|
||||
|
||||
## Legacy Tool Preservation
|
||||
|
||||
Original HTML files are kept in the repository under their current paths for reference:
|
||||
|
||||
```
|
||||
emailsignature/emailsignature-config.html
|
||||
wordXMLgenerator/word-xml-generator-basic.html
|
||||
wordXMLgenerator/word-xml-generator-medium.html
|
||||
wordXMLgenerator/word-xml-generator-advanced.html
|
||||
```
|
||||
|
||||
These files are not served by the Next.js application in production. They remain in the repository as:
|
||||
- Reference implementation for migration accuracy.
|
||||
- Fallback if a React module has a blocking bug.
|
||||
- Historical documentation of original tool behavior.
|
||||
|
||||
Once Phase 3 is complete and the React versions are stable, legacy files can be moved to a `legacy/` directory or archived in a separate branch. Do not delete them until the React versions have been in production use for at least one release cycle.
|
||||
Reference in New Issue
Block a user