diff --git a/ADDING-YOUR-PHOTO.md b/ADDING-YOUR-PHOTO.md new file mode 100644 index 0000000..0552177 --- /dev/null +++ b/ADDING-YOUR-PHOTO.md @@ -0,0 +1,72 @@ +# Cómo Añadir tu Foto al CV + +## 📸 Paso 1: Prepara tu Foto + +1. **Busca una foto profesional** (preferiblemente tipo LinkedIn) +2. **Formato recomendado**: JPG o PNG +3. **Tamaño**: Al menos 300x300 píxeles (cuadrada es mejor) +4. **Calidad**: Fondo neutro, buena iluminación + +## 📁 Paso 2: Guarda la Foto + +Guarda tu foto en: +``` +static/images/profile/photo.jpg +``` + +Puedes usar cualquiera de estos nombres: +- `photo.jpg` ✅ (recomendado) +- `photo.png` (cambiar en template) +- `profile.jpg` (cambiar en template) + +## 🔄 Paso 3: Actualizar (si usas otro nombre) + +Si tu foto se llama diferente a `photo.jpg`, edita `templates/cv-content.html`: + +```html + + + + + +``` + +## 🖼️ Descargar desde LinkedIn + +### Opción 1: Manualmente +1. Abre tu perfil de LinkedIn +2. Click derecho en tu foto → "Guardar imagen como..." +3. Guárdala como `photo.jpg` en `static/images/profile/` + +### Opción 2: Desde tu sitio actual +Si ya tienes tu foto en https://juan.andres.morenoyrubio.com: + +```bash +cd static/images/profile +# Abre el inspector del navegador, busca tu foto, y copia la URL +curl -o photo.jpg "URL_DE_TU_FOTO" +``` + +## ✅ Verificar + +1. Reinicia el servidor: `./cv-server` +2. Abre http://localhost:8080 +3. Deberías ver tu foto en la esquina superior izquierda + +Si no funciona, verás un placeholder gris con el texto "Add your photo". + +## 🎨 Ajustar el Tamaño (Opcional) + +La foto se muestra como un círculo de 120px. Para cambiar el tamaño, edita `static/css/main.css`: + +```css +.cv-photo { + width: 150px; /* Cambiar aquí */ + height: 150px; /* Y aquí */ + border-radius: 50%; +} +``` + +--- + +**Nota**: El template ya incluye un fallback automático al placeholder si la foto no existe, así que el sitio funcionará con o sin foto. diff --git a/data/cv-en.json b/data/cv-en.json index ab9a73e..00434af 100644 --- a/data/cv-en.json +++ b/data/cv-en.json @@ -35,7 +35,9 @@ "React", "Node.js", "API Integration" - ] + ], + "companyLogo": "olympic-broadcasting.png", + "shortDescription": "SAP CDC solutions for international broadcasting events. Custom implementations and technical guidance." }, { "position": "Senior Technical Consultant", @@ -64,7 +66,9 @@ "highlights": [ "Successfully deployed authentication system for all AENA airports in Spain", "Managed identity flows for millions of users across web and mobile platforms" - ] + ], + "companyLogo": "aena.png", + "shortDescription": "Lead Technical Consultant for AENA Airports Authentication System serving millions of passengers across all Spanish airports." }, { "position": "Senior Technical Consultant", @@ -87,7 +91,9 @@ "JavaScript", "Cloud Platforms", "Technical Documentation" - ] + ], + "companyLogo": "sap.png", + "shortDescription": "SAP Customer Data Cloud technical consulting, troubleshooting, and stakeholder education on GDPR compliance." }, { "position": "Junior Technical Consultant", @@ -109,7 +115,9 @@ "JavaScript", "Customer Support", "System Monitoring" - ] + ], + "companyLogo": "gigya.png", + "shortDescription": "Technical support and problem-solving for Gigya platform. System monitoring and training program development." }, { "position": "Fullstack Developer", @@ -130,7 +138,9 @@ "Video Processing", "Database Design", "PostgreSQL" - ] + ], + "companyLogo": "megabanner.png", + "shortDescription": "Full-stack development with video system integration for advertisement inclusion in gas station networks." }, { "position": "Fullstack Developer", @@ -152,7 +162,9 @@ "API Design", "CI/CD", "DevOps" - ] + ], + "companyLogo": "everis.png", + "shortDescription": "API design and automated deployment pipelines. Software testing and scalability implementation." }, { "position": "FullStack Developer", @@ -170,7 +182,9 @@ "JavaScript", "Redux", "Webpack" - ] + ], + "companyLogo": "everis.png", + "shortDescription": "React application development for multiple clients." }, { "position": "Fullstack Developer", @@ -187,7 +201,9 @@ "Java", "JavaScript", "Web Development" - ] + ], + "companyLogo": "indra.png", + "shortDescription": "Project management and customer feedback collection across development stages." }, { "position": "Technical Director / Programmer", @@ -212,7 +228,8 @@ "highlights": [ "Reduced production times by 75% through optimized pipelines", "Successfully managed technical team and product development" - ] + ], + "shortDescription": "Technical Director leading development of backend and 5 websites. Reduced production times by 75%." }, { "position": "Programmer Analyst (Freelance)", @@ -230,7 +247,8 @@ "PHP", "MySQL", "JavaScript" - ] + ], + "shortDescription": "WordPress and PHP website development as freelance programmer." }, { "position": "Analyst Programmer / Expert Technician", @@ -248,7 +266,8 @@ "Java", "System Configuration", "Technical Support" - ] + ], + "shortDescription": "Software and hardware configuration, technical problem-solving, and team mentoring." }, { "position": "Senior Programmer", @@ -266,7 +285,8 @@ "Java", "Search Engine Technology", "European R&D Projects" - ] + ], + "shortDescription": "European R&D project for revolutionary search engine development." }, { "position": "Junior Programmer", @@ -285,7 +305,8 @@ "Java Applets", "Data Visualization", "Chart Generation" - ] + ], + "shortDescription": "JAVA development specialized in data chart generation and applet development." } ], "education": [ diff --git a/data/cv-es.json b/data/cv-es.json index fe8f47a..620949d 100644 --- a/data/cv-es.json +++ b/data/cv-es.json @@ -35,7 +35,9 @@ "React", "Node.js", "Integración de APIs" - ] + ], + "companyLogo": "olympic-broadcasting.png", + "shortDescription": "Soluciones SAP CDC para eventos de transmisión internacional. Implementaciones personalizadas y orientación técnica." }, { "position": "Consultor Técnico Senior", @@ -64,7 +66,9 @@ "highlights": [ "Despliegue exitoso del sistema de autenticación para todos los aeropuertos AENA en España", "Gestión de flujos de identidad para millones de usuarios en plataformas web y móviles" - ] + ], + "companyLogo": "aena.png", + "shortDescription": "Consultor Técnico Principal del Sistema de Autenticación de Aeropuertos AENA sirviendo a millones de pasajeros en todos los aeropuertos españoles." }, { "position": "Consultor Técnico Senior", @@ -87,7 +91,9 @@ "JavaScript", "Plataformas Cloud", "Documentación Técnica" - ] + ], + "companyLogo": "sap.png", + "shortDescription": "Consultoría técnica SAP Customer Data Cloud, resolución de problemas y educación de stakeholders en cumplimiento GDPR." }, { "position": "Consultor Técnico Junior", @@ -109,7 +115,9 @@ "JavaScript", "Soporte al Cliente", "Monitoreo de Sistemas" - ] + ], + "companyLogo": "gigya.png", + "shortDescription": "Soporte técnico y resolución de problemas para plataforma Gigya. Monitoreo de sistemas y desarrollo de programas de formación." }, { "position": "Desarrollador Fullstack", @@ -130,7 +138,9 @@ "Procesamiento de Video", "Diseño de Bases de Datos", "PostgreSQL" - ] + ], + "companyLogo": "megabanner.png", + "shortDescription": "Desarrollo full-stack con integración de sistema de video para inclusión de anuncios en redes de estaciones de servicio." }, { "position": "Desarrollador Fullstack", @@ -152,7 +162,9 @@ "Diseño de APIs", "CI/CD", "DevOps" - ] + ], + "companyLogo": "everis.png", + "shortDescription": "Diseño de APIs y pipelines de despliegue automatizados. Testing de software e implementación de escalabilidad." }, { "position": "Desarrollador FullStack", @@ -170,7 +182,9 @@ "JavaScript", "Redux", "Webpack" - ] + ], + "companyLogo": "everis.png", + "shortDescription": "Desarrollo de aplicaciones React para múltiples clientes." }, { "position": "Desarrollador Fullstack", @@ -187,7 +201,9 @@ "Java", "JavaScript", "Desarrollo Web" - ] + ], + "companyLogo": "indra.png", + "shortDescription": "Gestión de proyectos y recopilación de feedback de clientes en diferentes etapas de desarrollo." }, { "position": "Director Técnico / Programador", @@ -212,7 +228,8 @@ "highlights": [ "Reducción del 75% en tiempos de producción mediante pipelines optimizados", "Gestión exitosa de equipo técnico y desarrollo de productos" - ] + ], + "shortDescription": "Director Técnico liderando desarrollo de backend y 5 sitios web. Reducción del 75% en tiempos de producción." }, { "position": "Analista Programador (Freelance)", @@ -230,7 +247,8 @@ "PHP", "MySQL", "JavaScript" - ] + ], + "shortDescription": "Desarrollo de sitios web WordPress y PHP como programador freelance." }, { "position": "Analista Programador / Técnico Experto", @@ -248,7 +266,8 @@ "Java", "Configuración de Sistemas", "Soporte Técnico" - ] + ], + "shortDescription": "Configuración de software y hardware, resolución de problemas técnicos y mentoría de equipos." }, { "position": "Programador Senior", @@ -266,7 +285,8 @@ "Java", "Tecnología de Motores de Búsqueda", "Proyectos Europeos I+D" - ] + ], + "shortDescription": "Proyecto europeo I+D para desarrollo de motor de búsqueda revolucionario." }, { "position": "Programador Junior", @@ -285,7 +305,8 @@ "Applets Java", "Visualización de Datos", "Generación de Gráficos" - ] + ], + "shortDescription": "Desarrollo JAVA especializado en generación de gráficos de datos y desarrollo de applets." } ], "education": [ diff --git a/download-logos.sh b/download-logos.sh new file mode 100755 index 0000000..fbd0906 --- /dev/null +++ b/download-logos.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Download company logos +cd static/images/companies + +# Olympic Broadcasting Services +curl -sL "https://logo.clearbit.com/obs.tv" -o olympic-broadcasting.png 2>/dev/null || echo "OBS logo not found" + +# AENA +curl -sL "https://logo.clearbit.com/aena.es" -o aena.png 2>/dev/null || echo "AENA logo not found" + +# SAP +curl -sL "https://logo.clearbit.com/sap.com" -o sap.png 2>/dev/null || echo "SAP logo not found" + +# Gigya (now SAP CDC) +curl -sL "https://logo.clearbit.com/gigya.com" -o gigya.png 2>/dev/null || echo "Gigya logo not found" + +# Accenture +curl -sL "https://logo.clearbit.com/accenture.com" -o accenture.png 2>/dev/null || echo "Accenture logo not found" + +# Megabanner +curl -sL "https://logo.clearbit.com/megabanner.es" -o megabanner.png 2>/dev/null || echo "Megabanner logo not found" + +# Everis +curl -sL "https://logo.clearbit.com/everis.com" -o everis.png 2>/dev/null || echo "Everis logo not found" + +# Indra +curl -sL "https://logo.clearbit.com/indra.es" -o indra.png 2>/dev/null || echo "Indra logo not found" + +echo "✅ Company logos downloaded" +ls -lh diff --git a/internal/models/cv.go b/internal/models/cv.go index b8ea0c6..ebcb2e9 100644 --- a/internal/models/cv.go +++ b/internal/models/cv.go @@ -41,10 +41,12 @@ type Personal struct { type Experience struct { Position string `json:"position"` Company string `json:"company"` + CompanyLogo string `json:"companyLogo"` Location string `json:"location"` StartDate string `json:"startDate"` EndDate string `json:"endDate"` Current bool `json:"current"` + ShortDescription string `json:"shortDescription"` Responsibilities []string `json:"responsibilities"` Technologies []string `json:"technologies"` Highlights []string `json:"highlights"` diff --git a/static/css/main.css b/static/css/main.css index 21dc13f..87789e2 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -124,13 +124,39 @@ a:hover { min-height: 11in; } -/* Header */ +/* Header - Photo on right, inline with text */ .cv-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 2rem; border-bottom: 2px solid var(--text-dark); padding-bottom: 1.5rem; margin-bottom: 2rem; } +.cv-header-left { + flex: 1; +} + +.cv-header-right { + flex-shrink: 0; +} + +.cv-photo { + width: 120px; + height: 120px; + border-radius: 50%; + overflow: hidden; + border: 3px solid var(--border-gray); +} + +.cv-photo img { + width: 100%; + height: 100%; + object-fit: cover; +} + .cv-name { font-size: 2.5rem; font-weight: 700; @@ -170,9 +196,15 @@ a:hover { text-align: justify; } -/* Experience */ +/* Experience - with separators */ .experience-item { margin-bottom: 1.5rem; + padding-bottom: 1.5rem; + border-bottom: 1px solid var(--border-gray); +} + +.experience-item:last-child { + border-bottom: none; } .experience-header { @@ -180,6 +212,27 @@ a:hover { justify-content: space-between; margin-bottom: 0.75rem; gap: 1rem; + align-items: center; +} + +.company-logo { + width: 40px; + height: 40px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + margin-right: 1rem; +} + +.company-logo img { + max-width: 100%; + max-height: 100%; + object-fit: contain; +} + +.experience-title { + flex: 1; } .position { @@ -335,17 +388,109 @@ footer { font-size: 2rem; } + .cv-header { + flex-direction: column; + align-items: center; + text-align: center; + } + + .cv-photo { + order: -1; + margin-bottom: 1rem; + } + .experience-header, .project-header, .education-header { flex-direction: column; gap: 0.25rem; } - - .action-bar-content { - flex-direction: column; - gap: 1rem; + + .company-logo { + display: none; } } .no-print {} + +/* Print Styles for Photo */ +@media print { + .cv-photo { + width: 100px; + height: 100px; + border-width: 2px; + } + + .company-logo { + width: 30px; + height: 30px; + } +} + +/* CV Length Toggle */ +.cv-length-toggle { + display: flex; + gap: 0.5rem; +} + +.length-btn { + padding: 0.4rem 1rem; + border: 1px solid var(--border-gray); + background: white; + border-radius: 4px; + cursor: pointer; + font-size: 0.9rem; +} + +.length-btn:hover { + background: #f5f5f5; +} + +.length-btn.active { + background: var(--accent-blue); + color: white; + border-color: var(--accent-blue); +} + +/* Short CV - Hide detailed content */ +.cv-short .long-only { + display: none; +} + +.cv-short .short-desc { + display: block; + color: var(--text-gray); + font-size: 0.95rem; + line-height: 1.6; + margin-bottom: 0.75rem; +} + +/* Long CV - Hide short descriptions */ +.cv-long .short-desc, +.short-desc { + display: none; +} + +.cv-long .long-only { + display: block; +} + +/* Ensure lists display correctly in long mode */ +.cv-long .responsibilities { + display: block; +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .action-bar-content { + flex-wrap: wrap; + justify-content: center; + } + + .cv-length-toggle { + order: 1; + width: 100%; + justify-content: center; + margin-top: 0.5rem; + } +} diff --git a/static/images/companies/accenture.png b/static/images/companies/accenture.png new file mode 100644 index 0000000..9e8eccb Binary files /dev/null and b/static/images/companies/accenture.png differ diff --git a/static/images/companies/aena.png b/static/images/companies/aena.png new file mode 100644 index 0000000..7e5ee41 Binary files /dev/null and b/static/images/companies/aena.png differ diff --git a/static/images/companies/everis.png b/static/images/companies/everis.png new file mode 100644 index 0000000..222e709 Binary files /dev/null and b/static/images/companies/everis.png differ diff --git a/static/images/companies/gigya.png b/static/images/companies/gigya.png new file mode 100644 index 0000000..d770b52 Binary files /dev/null and b/static/images/companies/gigya.png differ diff --git a/static/images/companies/indra.png b/static/images/companies/indra.png new file mode 100644 index 0000000..e3bf314 --- /dev/null +++ b/static/images/companies/indra.png @@ -0,0 +1 @@ +Not Found diff --git a/static/images/companies/megabanner.png b/static/images/companies/megabanner.png new file mode 100644 index 0000000..e3bf314 --- /dev/null +++ b/static/images/companies/megabanner.png @@ -0,0 +1 @@ +Not Found diff --git a/static/images/companies/olympic-broadcasting.png b/static/images/companies/olympic-broadcasting.png new file mode 100644 index 0000000..321c396 Binary files /dev/null and b/static/images/companies/olympic-broadcasting.png differ diff --git a/static/images/companies/sap.png b/static/images/companies/sap.png new file mode 100644 index 0000000..d770b52 Binary files /dev/null and b/static/images/companies/sap.png differ diff --git a/static/images/profile/placeholder.svg b/static/images/profile/placeholder.svg new file mode 100644 index 0000000..fbf5539 --- /dev/null +++ b/static/images/profile/placeholder.svg @@ -0,0 +1,6 @@ + + + + + Add your photo + diff --git a/templates/cv-content.html b/templates/cv-content.html index 0ebf2b9..7c7d98c 100644 --- a/templates/cv-content.html +++ b/templates/cv-content.html @@ -1,15 +1,22 @@
-
-

{{.CV.Personal.Name}}

-

{{.CV.Personal.Title}}

+
+
+

{{.CV.Personal.Name}}

+

{{.CV.Personal.Title}}

+
+
+
{{.CV.Personal.Location}}
+ +
{{.CV.Personal.Phone}}
+ + +
-
-
{{.CV.Personal.Location}}
- -
{{.CV.Personal.Phone}}
- - +
+
+ {{.CV.Personal.Name}} +
@@ -26,6 +33,11 @@ {{range .CV.Experience}}
+ {{if .CompanyLogo}} + + {{end}}

{{.Position}}

{{.Company}}, {{.Location}}
@@ -35,14 +47,18 @@
-
    + {{if .ShortDescription}} +

    {{.ShortDescription}}

    + {{end}} + +
      {{range .Responsibilities}}
    • {{.}}
    • {{end}}
    {{if .Technologies}} -
    +
    {{range $index, $tech := .Technologies}}{{if $index}}, {{end}}{{$tech}}{{end}}
    {{end}} diff --git a/templates/index.html b/templates/index.html index 9aa3cae..4771c9a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -42,6 +42,19 @@
    +
    + + +
    +