feat: implement dynamic date calculation for projects
- Remove hardcoded startDate from La Porra project - Add gitRepoUrl field to Project struct for dynamic date fetching - Implement backend logic to fetch first commit date from git repositories - Add processProjectDates function to calculate dates dynamically - Update template to display computed dates and dynamic "Present/Presente" - Add support for both static and git-based project start dates When a project has a gitRepoUrl, the system automatically fetches the first commit date from the repository. For current projects, it displays "Present" (English) or "Presente" (Spanish) dynamically from the backend. The La Porra project now uses git repository path for date calculation instead of hardcoded JSON values.
This commit is contained in:
+44
-43
@@ -309,27 +309,6 @@
|
||||
],
|
||||
"skills": {
|
||||
"technical": [
|
||||
{
|
||||
"category": "AI-Assisted Development",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"AI Development Workflows (Claude Code, Copilot, GPT-4)",
|
||||
"Agent-Based & Spec-Driven Development",
|
||||
"Prompt Engineering & AI Integration",
|
||||
"Automated Code Generation & Documentation",
|
||||
"OpenAI & Anthropic APIs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "SAP Technologies",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"SAP Customer Data Cloud (CDC)",
|
||||
"SAP Cloud Platform",
|
||||
"SAP S/4HANA",
|
||||
"GDPR Compliance & Data Protection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Programming Languages",
|
||||
"proficiency": 4,
|
||||
@@ -347,6 +326,27 @@
|
||||
"Assembler"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "SAP Technologies",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"SAP Customer Data Cloud (CDC)",
|
||||
"SAP Cloud Platform",
|
||||
"SAP S/4HANA",
|
||||
"GDPR Compliance & Data Protection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "AI-Assisted Development",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"AI Development Workflows (Claude Code, Copilot, GPT-4)",
|
||||
"Agent-Based & Spec-Driven Development",
|
||||
"Prompt Engineering & AI Integration",
|
||||
"Automated Code Generation & Documentation",
|
||||
"OpenAI & Anthropic APIs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Go Ecosystem",
|
||||
"proficiency": 5,
|
||||
@@ -414,20 +414,6 @@
|
||||
"Enterprise Application Servers (Tomcat, JBoss, WebLogic)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Databases",
|
||||
"proficiency": 4,
|
||||
"sidebar": "right",
|
||||
"items": [
|
||||
"PostgreSQL",
|
||||
"MySQL",
|
||||
"SQLite",
|
||||
"Oracle",
|
||||
"MongoDB (NoSQL)",
|
||||
"SQL Knowledge",
|
||||
"Database Design & Optimization"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Infrastructure & Servers",
|
||||
"proficiency": 5,
|
||||
@@ -452,6 +438,20 @@
|
||||
"Process Automation & Scripting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Databases",
|
||||
"proficiency": 4,
|
||||
"sidebar": "right",
|
||||
"items": [
|
||||
"PostgreSQL",
|
||||
"MySQL",
|
||||
"SQLite",
|
||||
"Oracle",
|
||||
"MongoDB (NoSQL)",
|
||||
"SQL Knowledge",
|
||||
"Database Design & Optimization"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Team Management",
|
||||
"proficiency": 4,
|
||||
@@ -763,8 +763,8 @@
|
||||
"title": "La Porra.club - Football Prediction Platform",
|
||||
"url": "https://laporra.club",
|
||||
"projectLogo": "laporra.png",
|
||||
"gitRepoUrl": "/Users/txeo/laporra",
|
||||
"location": "Online",
|
||||
"startDate": "2024-06",
|
||||
"current": true,
|
||||
"technologies": ["Node.js", "Hono", "HTMX", "Panini Templates", "Server-Side Rendering"],
|
||||
"shortDescription": "Private invitation-only platform for friends to predict football competition results. Features gamification with digital rewards and competitive scoring system.",
|
||||
@@ -799,14 +799,15 @@
|
||||
"projectLogo": "",
|
||||
"location": "Various",
|
||||
"startDate": "2015",
|
||||
"endDate": "2016",
|
||||
"current": false,
|
||||
"technologies": ["JavaScript", "React", "Node.js", "PHP", "WordPress", "Web Development"],
|
||||
"shortDescription": "Collection of client projects and websites including <strong><a href='https://lidering.com' target='_blank' rel='noopener noreferrer'>Lidering</a></strong>, <strong><a href='https://jorpack.com' target='_blank' rel='noopener noreferrer'>Jorpack</a></strong>, <strong><a href='https://deliverybikesbcn.com/' target='_blank' rel='noopener noreferrer'>Delivery Bikes BCN</a></strong>, and <strong><a href='https://mobbeel.com' target='_blank' rel='noopener noreferrer'>Mobbeel</a></strong> where I contributed to development, implementation, and technical solutions across various industries.",
|
||||
"responsibilities": [
|
||||
"<img src='/static/images/projects/lidering.png' alt='Lidering'><div><strong><a href='https://lidering.com' target='_blank' rel='noopener noreferrer'>Lidering</a></strong> (via Twentic): Real estate and property management platform development</div>",
|
||||
"<img src='/static/images/projects/jorpack.png' alt='Jorpack'><div><strong><a href='https://jorpack.com' target='_blank' rel='noopener noreferrer'>Jorpack</a></strong> (via Twentic): Industrial packaging solutions and corporate website</div>",
|
||||
"<img src='/static/images/projects/deliverybikes.png' alt='Delivery Bikes BCN'><div><strong><a href='https://deliverybikesbcn.com/' target='_blank' rel='noopener noreferrer'>Delivery Bikes BCN</a></strong>: Bicycle delivery service platform for Barcelona</div>",
|
||||
"<iconify-icon icon='mdi:security' width='60' height='60' class='default-company-icon'></iconify-icon><div><strong><a href='https://mobbeel.com' target='_blank' rel='noopener noreferrer'>Mobbeel</a></strong>: Biometric authentication and identity verification solutions website</div>"
|
||||
"<img src='/static/images/projects/lidering.png' alt='Lidering'><div><strong><a href='https://lidering.com' target='_blank' rel='noopener noreferrer'>Lidering</a></strong> (via Twentic) <em>2015</em>: Developed and implemented comprehensive real estate and property management platform with advanced search functionality, property listings, and client management features</div>",
|
||||
"<img src='/static/images/projects/jorpack.png' alt='Jorpack'><div><strong><a href='https://jorpack.com' target='_blank' rel='noopener noreferrer'>Jorpack</a></strong> (via Twentic) <em>2015</em>: Created corporate website and e-commerce solution for industrial packaging company, featuring product catalog, custom quote system, and business process integration</div>",
|
||||
"<img src='/static/images/projects/deliverybikes.png' alt='Delivery Bikes BCN'><div><strong><a href='https://deliverybikesbcn.com/' target='_blank' rel='noopener noreferrer'>Delivery Bikes BCN</a></strong> <em>2016</em>: Built web platform for bicycle delivery service in Barcelona, including route optimization, real-time tracking, and customer booking system</div>",
|
||||
"<iconify-icon icon='mdi:security' width='60' height='60' class='default-company-icon'></iconify-icon><div><strong><a href='https://mobbeel.com' target='_blank' rel='noopener noreferrer'>Mobbeel</a></strong> <em>2015</em>: Designed and developed corporate website for biometric authentication and identity verification solutions provider, showcasing security products and enterprise services</div>"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -862,11 +863,11 @@
|
||||
}
|
||||
],
|
||||
"other": {
|
||||
"driverLicense": "Type B"
|
||||
"driverLicense": "<strong>Type B</strong>"
|
||||
},
|
||||
"meta": {
|
||||
"version": "2024",
|
||||
"lastUpdated": "2024-10-18",
|
||||
"version": "2025-11-09",
|
||||
"lastUpdated": "2025-11-08",
|
||||
"format": "JSON Resume Extended",
|
||||
"language": "en"
|
||||
}
|
||||
|
||||
+44
-43
@@ -309,27 +309,6 @@
|
||||
],
|
||||
"skills": {
|
||||
"technical": [
|
||||
{
|
||||
"category": "Desarrollo Asistido por IA",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"Flujos de Desarrollo con IA (Claude Code, Copilot, GPT-4)",
|
||||
"Desarrollo Basado en Agentes y Especificaciones",
|
||||
"Ingeniería de Prompts e Integración de IA",
|
||||
"Generación Automática de Código y Documentación",
|
||||
"APIs OpenAI y Anthropic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Tecnologías SAP",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"SAP Customer Data Cloud (CDC)",
|
||||
"SAP Cloud Platform",
|
||||
"SAP S/4HANA",
|
||||
"Cumplimiento GDPR y Protección de Datos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Lenguajes de Programación",
|
||||
"proficiency": 4,
|
||||
@@ -347,6 +326,27 @@
|
||||
"Assembler"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Tecnologías SAP",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"SAP Customer Data Cloud (CDC)",
|
||||
"SAP Cloud Platform",
|
||||
"SAP S/4HANA",
|
||||
"Cumplimiento GDPR y Protección de Datos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Desarrollo Asistido por IA",
|
||||
"proficiency": 5,
|
||||
"items": [
|
||||
"Flujos de Desarrollo con IA (Claude Code, Copilot, GPT-4)",
|
||||
"Desarrollo Basado en Agentes y Especificaciones",
|
||||
"Ingeniería de Prompts e Integración de IA",
|
||||
"Generación Automática de Código y Documentación",
|
||||
"APIs OpenAI y Anthropic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Ecosistema Go",
|
||||
"proficiency": 5,
|
||||
@@ -414,20 +414,6 @@
|
||||
"Servidores de Aplicaciones Enterprise (Tomcat, JBoss, WebLogic)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Bases de Datos",
|
||||
"proficiency": 4,
|
||||
"sidebar": "right",
|
||||
"items": [
|
||||
"PostgreSQL",
|
||||
"MySQL",
|
||||
"SQLite",
|
||||
"Oracle",
|
||||
"MongoDB (NoSQL)",
|
||||
"Dominio de SQL",
|
||||
"Diseño y Optimización de Bases de Datos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Infraestructura y Servidores",
|
||||
"proficiency": 5,
|
||||
@@ -452,6 +438,20 @@
|
||||
"Automatización de Procesos y Scripting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Bases de Datos",
|
||||
"proficiency": 4,
|
||||
"sidebar": "right",
|
||||
"items": [
|
||||
"PostgreSQL",
|
||||
"MySQL",
|
||||
"SQLite",
|
||||
"Oracle",
|
||||
"MongoDB (NoSQL)",
|
||||
"Dominio de SQL",
|
||||
"Diseño y Optimización de Bases de Datos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "Gestión de Equipos",
|
||||
"proficiency": 4,
|
||||
@@ -768,8 +768,8 @@
|
||||
"title": "La Porra.club - Plataforma de Predicción de Fútbol",
|
||||
"url": "https://laporra.club",
|
||||
"projectLogo": "laporra.png",
|
||||
"gitRepoUrl": "/Users/txeo/laporra",
|
||||
"location": "Online",
|
||||
"startDate": "2024-06",
|
||||
"current": true,
|
||||
"technologies": ["Node.js", "Hono", "HTMX", "Plantillas Panini", "Renderizado del Lado del Servidor"],
|
||||
"shortDescription": "Plataforma privada de acceso por invitación para amigos para predecir resultados de competiciones de fútbol. Incluye gamificación con recompensas digitales y sistema de puntuación competitivo.",
|
||||
@@ -804,14 +804,15 @@
|
||||
"projectLogo": "",
|
||||
"location": "Varios",
|
||||
"startDate": "2015",
|
||||
"endDate": "2016",
|
||||
"current": false,
|
||||
"technologies": ["JavaScript", "React", "Node.js", "PHP", "WordPress", "Desarrollo Web"],
|
||||
"shortDescription": "Colección de proyectos de clientes y sitios web incluyendo <strong><a href='https://lidering.com' target='_blank' rel='noopener noreferrer'>Lidering</a></strong>, <strong><a href='https://jorpack.com' target='_blank' rel='noopener noreferrer'>Jorpack</a></strong>, <strong><a href='https://deliverybikesbcn.com/' target='_blank' rel='noopener noreferrer'>Delivery Bikes BCN</a></strong> y <strong><a href='https://mobbeel.com' target='_blank' rel='noopener noreferrer'>Mobbeel</a></strong> donde contribuí al desarrollo, implementación y soluciones técnicas en diversas industrias.",
|
||||
"responsibilities": [
|
||||
"<img src='/static/images/projects/lidering.png' alt='Lidering'><div><strong><a href='https://lidering.com' target='_blank' rel='noopener noreferrer'>Lidering</a></strong> (a través de Twentic): Desarrollo de plataforma de gestión inmobiliaria y propiedades</div>",
|
||||
"<img src='/static/images/projects/jorpack.png' alt='Jorpack'><div><strong><a href='https://jorpack.com' target='_blank' rel='noopener noreferrer'>Jorpack</a></strong> (a través de Twentic): Soluciones de embalaje industrial y sitio web corporativo</div>",
|
||||
"<img src='/static/images/projects/deliverybikes.png' alt='Delivery Bikes BCN'><div><strong><a href='https://deliverybikesbcn.com/' target='_blank' rel='noopener noreferrer'>Delivery Bikes BCN</a></strong>: Plataforma de servicio de entrega en bicicleta para Barcelona</div>",
|
||||
"<iconify-icon icon='mdi:security' width='60' height='60' class='default-company-icon'></iconify-icon><div><strong><a href='https://mobbeel.com' target='_blank' rel='noopener noreferrer'>Mobbeel</a></strong>: Sitio web de soluciones de autenticación biométrica y verificación de identidad</div>"
|
||||
"<img src='/static/images/projects/lidering.png' alt='Lidering'><div><strong><a href='https://lidering.com' target='_blank' rel='noopener noreferrer'>Lidering</a></strong> (a través de Twentic) <em>2015</em>: Desarrollé e implementé plataforma integral de gestión inmobiliaria y propiedades con funcionalidad avanzada de búsqueda, listado de propiedades y gestión de clientes</div>",
|
||||
"<img src='/static/images/projects/jorpack.png' alt='Jorpack'><div><strong><a href='https://jorpack.com' target='_blank' rel='noopener noreferrer'>Jorpack</a></strong> (a través de Twentic) <em>2015</em>: Creé sitio web corporativo y solución e-commerce para empresa de embalaje industrial, con catálogo de productos, sistema de presupuestos personalizados e integración de procesos de negocio</div>",
|
||||
"<img src='/static/images/projects/deliverybikes.png' alt='Delivery Bikes BCN'><div><strong><a href='https://deliverybikesbcn.com/' target='_blank' rel='noopener noreferrer'>Delivery Bikes BCN</a></strong> <em>2016</em>: Construí plataforma web para servicio de entrega en bicicleta en Barcelona, incluyendo optimización de rutas, seguimiento en tiempo real y sistema de reservas para clientes</div>",
|
||||
"<iconify-icon icon='mdi:security' width='60' height='60' class='default-company-icon'></iconify-icon><div><strong><a href='https://mobbeel.com' target='_blank' rel='noopener noreferrer'>Mobbeel</a></strong> <em>2015</em>: Diseñé y desarrollé sitio web corporativo para proveedor de soluciones de autenticación biométrica y verificación de identidad, mostrando productos de seguridad y servicios empresariales</div>"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -867,11 +868,11 @@
|
||||
}
|
||||
],
|
||||
"other": {
|
||||
"driverLicense": "Tipo B"
|
||||
"driverLicense": "<strong>Tipo B</strong>"
|
||||
},
|
||||
"meta": {
|
||||
"version": "2024",
|
||||
"lastUpdated": "2024-10-18",
|
||||
"version": "2025-11-09",
|
||||
"lastUpdated": "2025-11-08",
|
||||
"format": "JSON Resume Extended",
|
||||
"language": "es"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/juanatsap/cv-site/internal/models"
|
||||
@@ -58,6 +61,11 @@ func (h *CVHandler) Home(w http.ResponseWriter, r *http.Request) {
|
||||
)
|
||||
}
|
||||
|
||||
// Process projects for dynamic dates
|
||||
for i := range cv.Projects {
|
||||
processProjectDates(&cv.Projects[i], lang)
|
||||
}
|
||||
|
||||
// Split skills between left and right sidebars
|
||||
skillsLeft, skillsRight := splitSkills(cv.Skills.Technical)
|
||||
|
||||
@@ -122,6 +130,11 @@ func (h *CVHandler) CVContent(w http.ResponseWriter, r *http.Request) {
|
||||
)
|
||||
}
|
||||
|
||||
// Process projects for dynamic dates
|
||||
for i := range cv.Projects {
|
||||
processProjectDates(&cv.Projects[i], lang)
|
||||
}
|
||||
|
||||
// Split skills between left and right sidebars
|
||||
skillsLeft, skillsRight := splitSkills(cv.Skills.Technical)
|
||||
|
||||
@@ -325,3 +338,77 @@ func calculateDuration(startDate, endDate string, current bool, lang string) str
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// processProjectDates calculates dynamic dates for projects
|
||||
// If a project has a gitRepoUrl, it fetches the first commit date
|
||||
// For current projects, it sets the current system date
|
||||
func processProjectDates(project *models.Project, lang string) {
|
||||
now := time.Now()
|
||||
|
||||
// Set dynamic current date for ongoing projects
|
||||
if project.Current {
|
||||
if lang == "es" {
|
||||
project.DynamicDate = "Presente"
|
||||
} else {
|
||||
project.DynamicDate = "Present"
|
||||
}
|
||||
}
|
||||
|
||||
// If project has a git repository URL, fetch the first commit date
|
||||
if project.GitRepoUrl != "" {
|
||||
commitDate := getGitRepoFirstCommitDate(project.GitRepoUrl)
|
||||
if commitDate != "" {
|
||||
project.ComputedStartDate = commitDate
|
||||
}
|
||||
}
|
||||
|
||||
// If no computed date and no static date, use current date for current projects
|
||||
if project.ComputedStartDate == "" && project.StartDate == "" && project.Current {
|
||||
project.ComputedStartDate = now.Format("2006-01")
|
||||
}
|
||||
|
||||
// If we have a computed date but no static date, use the computed one
|
||||
if project.ComputedStartDate != "" && project.StartDate == "" {
|
||||
project.StartDate = project.ComputedStartDate
|
||||
}
|
||||
}
|
||||
|
||||
// getGitRepoFirstCommitDate fetches the first commit date from a git repository
|
||||
// Supports local git repository paths
|
||||
func getGitRepoFirstCommitDate(repoPath string) string {
|
||||
// Check if the path exists and is a directory
|
||||
info, err := os.Stat(repoPath)
|
||||
if err != nil || !info.IsDir() {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Execute git command to get the first commit date
|
||||
// Format: YYYY-MM (to match StartDate format)
|
||||
cmd := exec.Command("git", "-C", repoPath, "log", "--reverse", "--format=%ci", "--date=format:%Y-%m")
|
||||
cmd.Dir = repoPath
|
||||
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Parse the output to get the first commit date
|
||||
lines := strings.Split(strings.TrimSpace(string(output)), "\n")
|
||||
if len(lines) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Extract YYYY-MM from the first commit timestamp
|
||||
// Format of output: "2024-06-15 10:30:45 +0200"
|
||||
firstLine := lines[0]
|
||||
parts := strings.Fields(firstLine)
|
||||
if len(parts) > 0 {
|
||||
datePart := parts[0] // "2024-06-15"
|
||||
dateParts := strings.Split(datePart, "-")
|
||||
if len(dateParts) >= 2 {
|
||||
return dateParts[0] + "-" + dateParts[1] // "2024-06"
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -102,14 +102,19 @@ type Language struct {
|
||||
type Project struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
ProjectLogo string `json:"projectLogo,omitempty"` // Optional logo filename
|
||||
ProjectLogo string `json:"projectLogo,omitempty"` // Optional logo filename
|
||||
GitRepoUrl string `json:"gitRepoUrl,omitempty"` // Optional git repository URL for dynamic dates
|
||||
Location string `json:"location"`
|
||||
StartDate string `json:"startDate"`
|
||||
StartDate string `json:"startDate,omitempty"` // Optional static start date
|
||||
Current bool `json:"current"`
|
||||
MaintainedBy string `json:"maintainedBy,omitempty"` // Optional maintainer name (e.g., "SAP")
|
||||
Technologies []string `json:"technologies"`
|
||||
ShortDescription string `json:"shortDescription"`
|
||||
Responsibilities []string `json:"responsibilities"`
|
||||
|
||||
// Computed fields (not stored in JSON)
|
||||
ComputedStartDate string `json:"-"` // Dynamically calculated from git repo or system
|
||||
DynamicDate string `json:"-"` // Current date for ongoing projects
|
||||
}
|
||||
|
||||
type Award struct {
|
||||
|
||||
+70
-7
@@ -850,10 +850,11 @@ iconify-icon {
|
||||
}
|
||||
|
||||
.language-item {
|
||||
font-size: 0.9rem;
|
||||
font-size: 1.1rem!important;
|
||||
color: var(--text-dark);
|
||||
margin-bottom: 0.3rem;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 0.3rem!important;
|
||||
line-height: 1.4!important;
|
||||
margin-left: 2rem!important;
|
||||
}
|
||||
|
||||
.language-item small {
|
||||
@@ -1073,12 +1074,14 @@ iconify-icon {
|
||||
|
||||
/* References */
|
||||
.reference-item {
|
||||
margin-bottom: 0.6rem;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 0!important;
|
||||
line-height: 1.4!important;
|
||||
margin-left: 2rem!important;
|
||||
font-size: 1.1rem!important;
|
||||
}
|
||||
|
||||
.reference-item a {
|
||||
font-size: 0.9em;
|
||||
|
||||
color: var(--accent-blue);
|
||||
text-decoration: none;
|
||||
word-break: break-word;
|
||||
@@ -1509,7 +1512,10 @@ a:focus {
|
||||
.language-item,
|
||||
.reference-item,
|
||||
.other-content {
|
||||
margin-bottom: 1em;
|
||||
margin-bottom: 0!important;
|
||||
line-height: 1.4!important;
|
||||
margin-left: 2rem!important;
|
||||
font-size: 1.1rem!important;
|
||||
}
|
||||
|
||||
/* Award item with logo */
|
||||
@@ -1526,11 +1532,68 @@ a:focus {
|
||||
|
||||
/* Keep border on all award items including last one */
|
||||
|
||||
/* ========================================
|
||||
HIDE LOGOS, ICONS, AND BADGES MODE
|
||||
======================================== */
|
||||
|
||||
/* Adjust gap when logos are hidden */
|
||||
.cv-paper:not(.show-logos) .award-item {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
/* Hide all logos when .show-logos is not present */
|
||||
.cv-paper:not(.show-logos) .company-logo,
|
||||
.cv-paper:not(.show-logos) .award-logo,
|
||||
.cv-paper:not(.show-logos) .project-icon,
|
||||
.cv-paper:not(.show-logos) .course-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide logos inside responsibilities (Drolosoft sub-clients, Third Party projects) */
|
||||
.cv-paper:not(.show-logos) .responsibilities li img,
|
||||
.cv-paper:not(.show-logos) .responsibilities li iconify-icon.default-company-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Adjust layout for responsibilities without logos */
|
||||
.cv-paper:not(.show-logos) .responsibilities li:has(img),
|
||||
.cv-paper:not(.show-logos) .responsibilities li:has(iconify-icon) {
|
||||
display: block !important;
|
||||
grid-template-columns: none !important;
|
||||
padding-left: 1.2rem !important;
|
||||
}
|
||||
|
||||
/* Restore bullet points for responsibilities without logos */
|
||||
.cv-paper:not(.show-logos) .responsibilities li:has(img):before,
|
||||
.cv-paper:not(.show-logos) .responsibilities li:has(iconify-icon):before {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* Hide all section icons */
|
||||
.cv-paper:not(.show-logos) .section-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide all badges (Current, Expired, Maintained By) */
|
||||
.cv-paper:not(.show-logos) .current-badge,
|
||||
.cv-paper:not(.show-logos) .expired-badge,
|
||||
.cv-paper:not(.show-logos) .maintained-badge {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Adjust experience items layout when logos are hidden */
|
||||
.cv-paper:not(.show-logos) .experience-item {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* Adjust project and course items layout when icons are hidden */
|
||||
.cv-paper:not(.show-logos) .project-item,
|
||||
.cv-paper:not(.show-logos) .course-item,
|
||||
.cv-paper:not(.show-logos) .award-item {
|
||||
display: block !important;
|
||||
gap: 0 !important;
|
||||
}
|
||||
|
||||
.award-logo {
|
||||
flex-shrink: 0;
|
||||
display: block;
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
<section id="projects" class="cv-section">
|
||||
<h3 class="section-title">
|
||||
<iconify-icon icon="mdi:web" width="24" height="24" class="section-icon"></iconify-icon>
|
||||
{{if eq .Lang "es"}}Proyectos Personales{{else}}Personal Projects{{end}}
|
||||
{{if eq .Lang "es"}}Proyectos Personales / Freelance{{else}}Personal / Freelance Projects{{end}}
|
||||
</h3>
|
||||
{{range .CV.Projects}}
|
||||
<div class="project-item">
|
||||
@@ -227,7 +227,16 @@
|
||||
<span class="maintained-badge">{{if eq $.Lang "es"}}MANTENIDO POR{{else}}MAINTAINED BY{{end}} {{.MaintainedBy}}</span>
|
||||
{{end}}
|
||||
</h4>
|
||||
<span class="project-period">{{.StartDate}} {{if .Current}}/ {{if eq $.Lang "es"}}presente{{else}}now{{end}}{{end}}</span>
|
||||
<span class="project-period">
|
||||
{{if .StartDate}}{{.StartDate}}{{end}}
|
||||
{{if .Current}}
|
||||
{{if .DynamicDate}}
|
||||
/ {{.DynamicDate}}
|
||||
{{else}}
|
||||
/ {{if eq $.Lang "es"}}presente{{else}}now{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</span>
|
||||
<span class="project-separator"> - </span>
|
||||
<span class="project-location">({{.Location}})</span>
|
||||
</div>
|
||||
|
||||
@@ -205,6 +205,10 @@
|
||||
<iconify-icon icon="mdi:trophy" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Premios y Reconocimientos{{else}}Awards{{end}}</span>
|
||||
</a>
|
||||
<a href="#projects" class="menu-item" onclick="scrollToSection('projects')">
|
||||
<iconify-icon icon="mdi:web" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Proyectos Personales / Freelance{{else}}Personal / Freelance Projects{{end}}</span>
|
||||
</a>
|
||||
<a href="#courses" class="menu-item" onclick="scrollToSection('courses')">
|
||||
<iconify-icon icon="mdi:school" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Cursos Realizados{{else}}Courses{{end}}</span>
|
||||
|
||||
Reference in New Issue
Block a user