feat: add dynamic years calculation and complete CV content migration
- Add dynamic years of experience calculation from April 1, 2005 - Update professional title badges: ANALYST | TECHNICAL CONSULTANT - Add all missing skill categories from React CV (Programming Languages, JavaScript Frameworks, PHP Frameworks, Java Frameworks, Application Servers, CMS, Design Tools, Team Management) - Add complete References section with LinkedIn, Behance, portfolios, and recommendation letters - Refine years-of-experience subtitle styling to match original design - Achieve 100% content parity with old React CV (English: 7→14 skill categories)
This commit is contained in:
@@ -2,13 +2,15 @@
|
||||
<div class="cv-page page-1">
|
||||
<!-- Professional Title Badges - Full Width Top Bar -->
|
||||
<div class="cv-title-badges-header">
|
||||
<span class="title-badge">{{if eq .Lang "es"}}ANALISTA PROGRAMADOR{{else}}ANALYST PROGRAMMER{{end}}</span>
|
||||
<span class="title-badge">{{if eq .Lang "es"}}ANALISTA{{else}}ANALYST{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">{{if eq .Lang "es"}}CONSULTOR TÉCNICO{{else}}TECHNICAL CONSULTANT{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">NODEJS + REACTJS {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">WEB {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">GO+HTMX {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="title-badge">GO + HTMX {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">PHP {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
</div>
|
||||
@@ -34,6 +36,7 @@
|
||||
<div class="cv-header-content">
|
||||
<div class="cv-header-left">
|
||||
<h1 class="cv-name">{{.CV.Personal.Name}}</h1>
|
||||
<p class="years-experience">{{.YearsOfExperience}} {{if eq .Lang "es"}}años de experiencia{{else}}years of experience{{end}}</p>
|
||||
<!-- Intro/Excerpt Text - No section heading, just the text -->
|
||||
<div class="intro-text">{{.CV.Summary}}</div>
|
||||
</div>
|
||||
@@ -124,7 +127,7 @@
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">WEB {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">GO+HTMX {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="title-badge">GO + HTMX {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
<span class="badge-separator">|</span>
|
||||
<span class="title-badge">PHP {{if eq .Lang "es"}}DESARROLLADOR{{else}}DEVELOPER{{end}}</span>
|
||||
</div>
|
||||
@@ -241,6 +244,13 @@
|
||||
<a href="mailto:{{.CV.Personal.Email}}" target="_blank" rel="noopener noreferrer">{{.CV.Personal.Email}}</a>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="footer-label">phone#</div>
|
||||
<div class="footer-separator"><i class="fa fa-circle"></i></div>
|
||||
<div class="footer-value">
|
||||
<a href="tel:+34676875420" target="_blank" rel="noopener noreferrer">+34 676 875 420</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
+53
-48
@@ -94,55 +94,45 @@
|
||||
<!-- Single Black Bar with Everything -->
|
||||
<div class="action-bar no-print" role="navigation" aria-label="Language and export controls">
|
||||
<div class="action-bar-content">
|
||||
<!-- Left: Language buttons -->
|
||||
<div class="language-toggle" role="group" aria-label="Language selection">
|
||||
<button
|
||||
class="lang-btn {{if eq .Lang "en"}}active{{end}}"
|
||||
hx-get="/cv?lang=en"
|
||||
hx-target="#cv-content"
|
||||
hx-swap="innerHTML swap:200ms settle:200ms"
|
||||
hx-push-url="/?lang=en"
|
||||
hx-indicator="#loading"
|
||||
aria-label="Switch to English"
|
||||
aria-pressed="{{if eq .Lang "en"}}true{{else}}false{{end}}">
|
||||
English
|
||||
</button>
|
||||
<button
|
||||
class="lang-btn {{if eq .Lang "es"}}active{{end}}"
|
||||
hx-get="/cv?lang=es"
|
||||
hx-target="#cv-content"
|
||||
hx-swap="innerHTML swap:200ms settle:200ms"
|
||||
hx-push-url="/?lang=es"
|
||||
hx-indicator="#loading"
|
||||
aria-label="Switch to Spanish"
|
||||
aria-pressed="{{if eq .Lang "es"}}true{{else}}false{{end}}">
|
||||
Español
|
||||
</button>
|
||||
<!-- Left: Site Title -->
|
||||
<div class="site-title">
|
||||
<svg class="site-icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20M10,19H8V14H10V19M14,19H12V12H14V19M10,11H8V9H10V11Z"/>
|
||||
</svg>
|
||||
<span class="site-title-text">{{if eq .Lang "es"}}Curriculum Vitae 2025{{else}}Curriculum Vitae 2025{{end}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Center: Toggle controls -->
|
||||
<div class="toggle-controls-center">
|
||||
<!-- Language toggle -->
|
||||
<div class="language-toggle">
|
||||
<span class="toggle-label-left">EN</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="langToggle" {{if eq .Lang "es"}}checked{{end}} onclick="toggleLanguage()" aria-label="{{if eq .Lang "es"}}Switch to English{{else}}Switch to Spanish{{end}}">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
<span class="toggle-label-right">ES</span>
|
||||
</div>
|
||||
|
||||
<!-- Center: CV Length Toggle -->
|
||||
<div class="cv-length-toggle">
|
||||
<button
|
||||
class="length-btn active"
|
||||
onclick="toggleCVLength('short')"
|
||||
aria-label="{{if eq .Lang "es"}}Ver CV corto{{else}}View short CV{{end}}">
|
||||
{{if eq .Lang "es"}}Corto{{else}}Short{{end}}
|
||||
</button>
|
||||
<button
|
||||
class="length-btn"
|
||||
onclick="toggleCVLength('long')"
|
||||
aria-label="{{if eq .Lang "es"}}Ver CV largo{{else}}View long CV{{end}}">
|
||||
{{if eq .Lang "es"}}Largo{{else}}Long{{end}}
|
||||
</button>
|
||||
<span class="toggle-label-left">{{if eq .Lang "es"}}Corto{{else}}Short{{end}}</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="lengthToggle" onclick="toggleCVLength()" aria-label="{{if eq .Lang "es"}}Cambiar longitud del CV{{else}}Toggle CV length{{end}}">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
<span class="toggle-label-right">{{if eq .Lang "es"}}Largo{{else}}Long{{end}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Center Right: Logo Toggle -->
|
||||
<div class="logo-toggle">
|
||||
<span class="toggle-label-left">{{if eq .Lang "es"}}Sin logos{{else}}No logos{{end}}</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="logoToggle" onclick="toggleLogos()" aria-label="{{if eq .Lang "es"}}Mostrar logos de empresas{{else}}Show company logos{{end}}">
|
||||
<span class="toggle-slider"></span>
|
||||
<span class="toggle-label">{{if eq .Lang "es"}}Mostrar logos{{else}}Show logos{{end}}</span>
|
||||
</label>
|
||||
<span class="toggle-label-right">{{if eq .Lang "es"}}Logos{{else}}Logos{{end}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: Action buttons -->
|
||||
@@ -202,21 +192,36 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleCVLength(length) {
|
||||
// Update button states
|
||||
document.querySelectorAll('.length-btn').forEach(btn => {
|
||||
btn.classList.remove('active');
|
||||
});
|
||||
event.target.classList.add('active');
|
||||
function toggleLanguage() {
|
||||
const checkbox = document.getElementById('langToggle');
|
||||
const lang = checkbox.checked ? 'es' : 'en';
|
||||
|
||||
// Toggle visibility
|
||||
// Use HTMX to load new content
|
||||
htmx.ajax('GET', `/cv?lang=${lang}`, {
|
||||
target: '#cv-content',
|
||||
swap: 'innerHTML swap:200ms settle:200ms',
|
||||
indicator: '#loading'
|
||||
});
|
||||
|
||||
// Update URL
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.set('lang', lang);
|
||||
window.history.pushState({}, '', url);
|
||||
|
||||
// Update html lang attribute
|
||||
document.documentElement.lang = lang;
|
||||
}
|
||||
|
||||
function toggleCVLength() {
|
||||
const checkbox = document.getElementById('lengthToggle');
|
||||
const paper = document.querySelector('.cv-paper');
|
||||
if (length === 'short') {
|
||||
paper.classList.add('cv-short');
|
||||
paper.classList.remove('cv-long');
|
||||
} else {
|
||||
|
||||
if (checkbox.checked) {
|
||||
paper.classList.add('cv-long');
|
||||
paper.classList.remove('cv-short');
|
||||
} else {
|
||||
paper.classList.add('cv-short');
|
||||
paper.classList.remove('cv-long');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user