diff --git a/PDF-EXPORT-FEATURE.md b/PDF-EXPORT-FEATURE.md index 18bc24b..26f22eb 100644 --- a/PDF-EXPORT-FEATURE.md +++ b/PDF-EXPORT-FEATURE.md @@ -8,13 +8,13 @@ The CV application provides a comprehensive PDF export system with three predefi ### Export Options -#### 1. Short CV (Clean Version - **Detailed**) -- **Length**: `detailed` (essential information only) +#### 1. Short CV (Clean Version - **Short**) +- **Length**: `short` (essential information only) - **Version**: `clean` (no skills sidebar) - **Page Count**: 4 pages - **Use Case**: Job applications requiring concise CVs -- **Parameters**: `?lang={lang}&length=detailed&icons=show&version=clean` -- **Filename**: `cv-detailed-jamr-{year}-{lang}.pdf` *(version omitted for clean)* +- **Parameters**: `?lang={lang}&length=short&icons=show&version=clean` +- **Filename**: `cv-short-jamr-{year}-{lang}.pdf` *(version omitted for clean)* #### 2. Long CV (Extended Version - **With Skills**) - **Length**: `extended` (comprehensive information) @@ -40,7 +40,7 @@ All exported PDFs follow a consistent, intuitive naming convention: cv-{length}[-{version}]-{initials}-{year}-{lang}.pdf WHERE: - {length} = detailed | extended + {length} = short | extended {version} = OMITTED for clean | with_skills for extended {initials} = User initials (e.g., "jamr") {year} = Current year (2025) @@ -53,17 +53,17 @@ WHERE: | Modal Option | Settings | Generated Filename | |-------------|----------|-------------------| -| **Short CV** | detailed + clean | `cv-detailed-jamr-2025-es.pdf` | +| **Short CV** | short + clean | `cv-short-jamr-2025-es.pdf` | | **Long CV** | extended + with_skills | `cv-extended-with_skills-jamr-2025-en.pdf` | -| **Current View** | detailed + with_skills | `cv-detailed-with_skills-jamr-2025-es.pdf` | +| **Current View** | short + with_skills | `cv-short-with_skills-jamr-2025-es.pdf` | | **Current View** | extended + clean | `cv-extended-jamr-2025-en.pdf` | ### Comprehensive Combinations Matrix | Length | Version | Filename Pattern | |--------|---------|------------------| -| **detailed** | clean | `cv-detailed-jamr-{year}-{lang}.pdf` | -| **detailed** | with_skills | `cv-detailed-with_skills-jamr-{year}-{lang}.pdf` | +| **short** | clean | `cv-short-jamr-{year}-{lang}.pdf` | +| **short** | with_skills | `cv-short-with_skills-jamr-{year}-{lang}.pdf` | | **extended** | clean | `cv-extended-jamr-{year}-{lang}.pdf` | | **extended** | with_skills | `cv-extended-with_skills-jamr-{year}-{lang}.pdf` | @@ -75,7 +75,7 @@ Static PDF URLs in JSON data files use a `{{YEAR}}` placeholder that's automatic **JSON Configuration:** ```json { - "url": "https://juan.andres.morenorub.io/static/pdf/cv-detailed-jamr-{{YEAR}}-es.pdf" + "url": "https://juan.andres.morenorub.io/static/pdf/cv-short-jamr-{{YEAR}}-es.pdf" } ``` @@ -105,10 +105,10 @@ initials = strings.ToLower(initials) For backwards compatibility, the system automatically maps old localStorage values to the new naming convention: ```javascript -// Old → New mapping -'short' → 'detailed' +// Old → New mapping (for backwards compatibility) 'long' → 'extended' 'extended' (theme) → 'with_skills' +// Note: 'short' now stays as 'short' (no longer maps to 'detailed') 'clean' → 'clean' (unchanged) ``` @@ -218,8 +218,8 @@ This defense-in-depth approach guarantees light mode PDFs even if: │ │ └── 04-interactive/ │ │ └── _remaining.css # Modal styling (red theme for PDF) │ └── pdf/ -│ ├── cv-detailed-jamr-2025-es.pdf -│ ├── cv-detailed-jamr-2025-en.pdf +│ ├── cv-short-jamr-2025-es.pdf +│ ├── cv-short-jamr-2025-en.pdf │ ├── cv-extended-with_skills-jamr-2025-es.pdf │ └── cv-extended-with_skills-jamr-2025-en.pdf ├── data/ @@ -237,13 +237,13 @@ This defense-in-depth approach guarantees light mode PDFs even if: **Parameter Validation:** ```go -// Length parameter: "detailed" or "extended" +// Length parameter: "short" or "extended" length := r.URL.Query().Get("length") if length == "" { - length = "detailed" + length = "short" } -if length != "detailed" && length != "extended" { - HandleError(w, r, BadRequestError("Unsupported length. Use 'detailed' or 'extended'")) +if length != "short" && length != "extended" { + HandleError(w, r, BadRequestError("Unsupported length. Use 'short' or 'extended'")) return } @@ -284,7 +284,7 @@ if version == "clean" { ``` **Examples:** -- detailed + clean → `cv-detailed-jamr-2025-es.pdf` +- short + clean → `cv-short-jamr-2025-es.pdf` - extended + with_skills → `cv-extended-with_skills-jamr-2025-en.pdf` ### Frontend: Modal Interaction with Legacy Mapping @@ -299,8 +299,8 @@ function downloadPDF() { let url; if (selectedFormat === 'short') { - // Short CV: clean version (no skills), detailed length - url = `/export/pdf?lang=${lang}&length=detailed&icons=show&version=clean`; + // Short CV: clean version (no skills), short length + url = `/export/pdf?lang=${lang}&length=short&icons=show&version=clean`; } else if (selectedFormat === 'long') { // Long CV: with skills sidebar, extended length url = `/export/pdf?lang=${lang}&length=extended&icons=show&version=with_skills`; @@ -309,8 +309,8 @@ function downloadPDF() { let currentLength = localStorage.getItem('cv-length') || 'short'; // Map old values to new naming convention - if (currentLength === 'short') currentLength = 'detailed'; if (currentLength === 'long') currentLength = 'extended'; + // 'short' stays as 'short' - no mapping needed const currentIcons = localStorage.getItem('cv-icons') || 'show'; const currentTheme = localStorage.getItem('cv-theme') || 'default'; @@ -339,13 +339,13 @@ Tests the modal interface and user interactions: #### 2. Parameter Validation Test: `24-pdf-download-params.test.mjs` Tests PDF export parameters and filename generation: -- ✅ Short CV parameters: `length=detailed&version=clean` +- ✅ Short CV parameters: `length=short&version=clean` - ✅ Long CV parameters: `length=extended&version=with_skills` - ✅ Current View parameters: reads from localStorage with mapping - ✅ Filename format: `cv-{length}[-{version}]-{initials}-{year}-{lang}.pdf` - ✅ Version omitted for clean - ✅ Dynamic year generation -- ✅ Legacy value mapping (short→detailed, long→extended) +- ✅ Legacy value mapping (long→extended) **Run Tests:** ```bash @@ -381,7 +381,7 @@ bun tests/run-all.mjs **Parameters:** - `lang` (optional, default: "en"): `es` or `en` -- `length` (optional, default: "detailed"): `detailed` or `extended` +- `length` (optional, default: "short"): `short` or `extended` - `icons` (optional, default: "show"): `show` or `hide` - `version` (optional, default: "with_skills"): `clean` or `with_skills` @@ -392,9 +392,9 @@ bun tests/run-all.mjs **Example Requests:** ```bash -# Detailed clean CV in Spanish -curl -O http://localhost:1999/export/pdf?lang=es&length=detailed&icons=show&version=clean -# Filename: cv-detailed-jamr-2025-es.pdf +# Short clean CV in Spanish +curl -O http://localhost:1999/export/pdf?lang=es&length=short&icons=show&version=clean +# Filename: cv-short-jamr-2025-es.pdf # Extended with skills CV in English curl -O http://localhost:1999/export/pdf?lang=en&length=extended&icons=show&version=with_skills @@ -405,7 +405,7 @@ curl -O http://localhost:1999/export/pdf?lang=en&length=extended&icons=show&vers ### Why This Naming Convention? -1. **Clarity**: "detailed" and "extended" clearly communicate content depth +1. **Clarity**: "short" and "extended" clearly communicate content depth 2. **Simplicity**: Version omitted for clean keeps filenames concise 3. **Consistency**: All components follow the same pattern 4. **Intuitive**: Non-technical users can understand what each filename means @@ -415,7 +415,7 @@ curl -O http://localhost:1999/export/pdf?lang=en&length=extended&icons=show&vers | Old Naming | New Naming | Improvement | |-----------|------------|-------------| -| `cv-short-clean-es-jamr-2025.pdf` | `cv-detailed-jamr-2025-es.pdf` | Clearer, more concise | +| `cv-detailed-jamr-2025-es.pdf` (v1) | `cv-short-jamr-2025-es.pdf` | Simpler, more intuitive | | `cv-long-extended-en-jamr-2025.pdf` | `cv-extended-with_skills-jamr-2025-en.pdf` | More descriptive, better clarity | | Language before year | Language after year | Better organization | @@ -426,12 +426,12 @@ curl -O http://localhost:1999/export/pdf?lang=en&length=extended&icons=show&vers To regenerate static PDFs referenced in JSON files: ```bash -# Detailed + clean (version omitted) -curl -o static/pdf/cv-detailed-jamr-2025-es.pdf \ - "http://localhost:1999/export/pdf?lang=es&length=detailed&icons=show&version=clean" +# Short + clean (version omitted) +curl -o static/pdf/cv-short-jamr-2025-es.pdf \ + "http://localhost:1999/export/pdf?lang=es&length=short&icons=show&version=clean" -curl -o static/pdf/cv-detailed-jamr-2025-en.pdf \ - "http://localhost:1999/export/pdf?lang=en&length=detailed&icons=show&version=clean" +curl -o static/pdf/cv-short-jamr-2025-en.pdf \ + "http://localhost:1999/export/pdf?lang=en&length=short&icons=show&version=clean" # Extended + with_skills curl -o static/pdf/cv-extended-with_skills-jamr-2025-es.pdf \ @@ -475,7 +475,7 @@ The system automatically handles year rollovers: **Symptom**: 400 Bad Request when downloading PDF **Solutions:** -1. Check allowed values: `length` ∈ {detailed, extended}, `version` ∈ {clean, with_skills} +1. Check allowed values: `length` ∈ {short, extended}, `version` ∈ {clean, with_skills} 2. Verify frontend sends correct parameters 3. Check browser network tab for actual request 4. Run parameter validation test: `bun tests/mjs/24-pdf-download-params.test.mjs` @@ -524,7 +524,7 @@ The system automatically handles year rollovers: ```bash # Set user to dark mode # Then generate PDF - curl -O "http://localhost:1999/export/pdf?lang=es&length=detailed&version=clean" + curl -O "http://localhost:1999/export/pdf?lang=es&length=short&version=clean" # Open PDF and verify it has white background ``` @@ -540,17 +540,18 @@ The system automatically handles year rollovers: **🎯 Major Changes:** #### 1. Complete Naming Convention Overhaul -- **BREAKING**: Changed from `short/long` to `detailed/extended` for better clarity +- **BREAKING**: Changed from `short/long` to `short/extended` for better clarity - **BREAKING**: Changed from `extended` (theme) to `with_skills` for better clarity - **NEW**: Version omitted from filename when `clean` (no skills sidebar) - **NEW**: Language moved to end: `cv-{length}[-{version}]-{initials}-{year}-{lang}.pdf` +- **UPDATE**: Originally used `detailed/extended`, changed to `short/extended` for better contrast **Old Naming Examples:** -- ❌ `cv-short-clean-es-jamr-2025.pdf` -- ❌ `cv-long-extended-en-jamr-2025.pdf` +- ❌ `cv-short-clean-es-jamr-2025.pdf` (v0) +- ❌ `cv-long-extended-en-jamr-2025.pdf` (v0) **New Naming Examples:** -- ✅ `cv-detailed-jamr-2025-es.pdf` (version omitted) +- ✅ `cv-short-jamr-2025-es.pdf` (version omitted, final naming) - ✅ `cv-extended-with_skills-jamr-2025-en.pdf` (version included) #### 2. Light Mode Enforcement - Defense in Depth @@ -583,17 +584,17 @@ The system automatically handles year rollovers: #### 4. Frontend Updates - **Updated**: PDF modal JavaScript to use new parameters - **Added**: Legacy localStorage mapping for backwards compatibility - - `short` → `detailed` - `long` → `extended` - `extended` (theme) → `with_skills` + - Note: `short` now stays as `short` (no longer maps to `detailed`) #### 5. Static Assets - **Generated**: 4 new PDFs with correct naming convention (2.2 MB each) - - `cv-detailed-jamr-2025-es.pdf` - - `cv-detailed-jamr-2025-en.pdf` + - `cv-short-jamr-2025-es.pdf` (updated from `cv-detailed`) + - `cv-short-jamr-2025-en.pdf` (updated from `cv-detailed`) - `cv-extended-with_skills-jamr-2025-es.pdf` - `cv-extended-with_skills-jamr-2025-en.pdf` -- **Removed**: Old PDFs with deprecated naming convention +- **Removed**: Old PDFs with deprecated naming (`cv-detailed-*`) #### 6. Documentation - **NEW**: "Print-Friendly Design: Light Mode Only" section diff --git a/data/cv-en.json b/data/cv-en.json index 15116f9..0cabb94 100644 --- a/data/cv-en.json +++ b/data/cv-en.json @@ -902,7 +902,7 @@ }, { "title": "Download this curriculum in English", - "url": "https://juan.andres.morenorub.io/static/pdf/cv-detailed-jamr-{{YEAR}}-en.pdf", + "url": "https://juan.andres.morenorub.io/static/pdf/cv-short-jamr-{{YEAR}}-en.pdf", "type": "cv", "textBefore": "Download this curriculum in", "linkText": "English" diff --git a/data/cv-es.json b/data/cv-es.json index a4d1135..d29032c 100644 --- a/data/cv-es.json +++ b/data/cv-es.json @@ -907,7 +907,7 @@ }, { "title": "Descargar este currículum en Español", - "url": "https://juan.andres.morenorub.io/static/pdf/cv-detailed-jamr-{{YEAR}}-es.pdf", + "url": "https://juan.andres.morenorub.io/static/pdf/cv-short-jamr-{{YEAR}}-es.pdf", "type": "cv", "textBefore": "Descargar este currículum en", "linkText": "Español" diff --git a/static/pdf/cv-detailed-jamr-2025-en.pdf b/static/pdf/cv-short-jamr-2025-en.pdf similarity index 99% rename from static/pdf/cv-detailed-jamr-2025-en.pdf rename to static/pdf/cv-short-jamr-2025-en.pdf index b673a39..39e10e3 100644 Binary files a/static/pdf/cv-detailed-jamr-2025-en.pdf and b/static/pdf/cv-short-jamr-2025-en.pdf differ diff --git a/static/pdf/cv-detailed-jamr-2025-es.pdf b/static/pdf/cv-short-jamr-2025-es.pdf similarity index 99% rename from static/pdf/cv-detailed-jamr-2025-es.pdf rename to static/pdf/cv-short-jamr-2025-es.pdf index 370a0f6..c86a625 100644 Binary files a/static/pdf/cv-detailed-jamr-2025-es.pdf and b/static/pdf/cv-short-jamr-2025-es.pdf differ diff --git a/templates/partials/modals/pdf-modal.html b/templates/partials/modals/pdf-modal.html index ea25817..f696b48 100644 --- a/templates/partials/modals/pdf-modal.html +++ b/templates/partials/modals/pdf-modal.html @@ -247,8 +247,8 @@ console.log('Download requested for format:', selectedFormat); if (selectedFormat === 'short') { - // Short CV: clean version (no skills), detailed length - url = `/export/pdf?lang=${lang}&length=detailed&icons=show&version=clean`; + // Short CV: clean version (no skills), short length + url = `/export/pdf?lang=${lang}&length=short&icons=show&version=clean`; } else if (selectedFormat === 'long') { // Long CV: with skills sidebar, extended length url = `/export/pdf?lang=${lang}&length=extended&icons=show&version=with_skills`; @@ -256,8 +256,8 @@ // Current view: use localStorage settings let currentLength = localStorage.getItem('cv-length') || 'short'; // Map old values to new naming convention - if (currentLength === 'short') currentLength = 'detailed'; if (currentLength === 'long') currentLength = 'extended'; + // 'short' stays as 'short' - no mapping needed const currentIcons = localStorage.getItem('cv-icons') || 'show'; const currentTheme = localStorage.getItem('cv-theme') || 'default';