more htmx
This commit is contained in:
@@ -11,41 +11,7 @@
|
||||
<button
|
||||
class="action-btn print-btn"
|
||||
aria-label="{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}"
|
||||
_="on click
|
||||
-- Store current state
|
||||
set wasClean to .cv-container.classList.contains('theme-clean')
|
||||
set wasLong to .cv-paper.classList.contains('cv-long')
|
||||
set currentZoom to localStorage.getItem('cv-zoom') or '100'
|
||||
|
||||
-- Apply print-friendly settings
|
||||
if not wasClean then add .theme-clean to .cv-container end
|
||||
remove .cv-long from .cv-paper
|
||||
add .cv-short to .cv-paper
|
||||
|
||||
-- Reset zoom for printing (directly set wrapper zoom to 1)
|
||||
set #zoom-wrapper's *zoom to 1
|
||||
|
||||
-- Let CSS apply, then print
|
||||
wait 50ms
|
||||
call window.print()
|
||||
|
||||
-- Wait for print dialog to close, then restore
|
||||
wait 100ms
|
||||
|
||||
-- Restore original theme
|
||||
if not wasClean then remove .theme-clean from .cv-container end
|
||||
|
||||
-- Restore original length
|
||||
if wasLong
|
||||
remove .cv-short from .cv-paper
|
||||
add .cv-long to .cv-paper
|
||||
end
|
||||
|
||||
-- Restore original zoom by triggering slider input event
|
||||
if currentZoom !== '100'
|
||||
set #zoom-slider's value to currentZoom
|
||||
send input to #zoom-slider
|
||||
end">
|
||||
_="on click call printFriendly()">
|
||||
<iconify-icon icon="mdi:leaf" width="18" height="18"></iconify-icon>
|
||||
{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}
|
||||
</button>
|
||||
|
||||
@@ -10,39 +10,48 @@
|
||||
<iconify-icon icon="mdi:chevron-right" width="16" height="16" class="submenu-arrow"></iconify-icon>
|
||||
</a>
|
||||
<div class="submenu-content">
|
||||
<a href="#education" class="menu-item">
|
||||
<a href="#education" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('education').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:school" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Formación{{else}}Training{{end}}</span>
|
||||
</a>
|
||||
<a href="#skills" class="menu-item">
|
||||
<a href="#skills" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('skills').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:brain" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Competencias{{else}}Skills{{end}}</span>
|
||||
</a>
|
||||
<a href="#experience" class="menu-item">
|
||||
<a href="#experience" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('experience').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:office-building" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Experiencia{{else}}Experience{{end}}</span>
|
||||
</a>
|
||||
<a href="#awards" class="menu-item">
|
||||
<a href="#awards" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('awards').scrollIntoView({behavior: 'smooth'})">
|
||||
<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">
|
||||
<a href="#projects" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('projects').scrollIntoView({behavior: 'smooth'})">
|
||||
<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">
|
||||
<a href="#courses" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('courses').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:school" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Cursos Realizados{{else}}Courses{{end}}</span>
|
||||
</a>
|
||||
<a href="#languages" class="menu-item">
|
||||
<a href="#languages" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('languages').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:translate" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Idiomas{{else}}Languages{{end}}</span>
|
||||
</a>
|
||||
<a href="#references" class="menu-item">
|
||||
<a href="#references" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('references').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:link-variant" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Referencias{{else}}References{{end}}</span>
|
||||
</a>
|
||||
<a href="#other" class="menu-item">
|
||||
<a href="#other" class="menu-item"
|
||||
_="on click call event.preventDefault() then call document.getElementById('other').scrollIntoView({behavior: 'smooth'})">
|
||||
<iconify-icon icon="mdi:information" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Otros{{else}}Other{{end}}</span>
|
||||
</a>
|
||||
@@ -69,7 +78,7 @@
|
||||
halt the event
|
||||
remove { display: 'none' } from #zoom-control
|
||||
add { display: 'none' } to me
|
||||
set localStorage.cv-zoom-visible to 'true'">
|
||||
set localStorage['cv-zoom-visible'] to 'true'">
|
||||
<iconify-icon icon="mdi:magnify" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Zoom{{else}}Zoom{{end}}</span>
|
||||
</a>
|
||||
@@ -83,7 +92,7 @@
|
||||
</div>
|
||||
|
||||
<!-- CV Length toggle -->
|
||||
<div class="menu-control-item">
|
||||
<div class="menu-control-item" id="mobile-length-toggle">
|
||||
<label class="menu-control-label">
|
||||
<iconify-icon icon="mdi:file-document-outline" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Longitud{{else}}Length{{end}}</span>
|
||||
@@ -92,10 +101,19 @@
|
||||
<input type="checkbox"
|
||||
id="lengthToggleMenu"
|
||||
{{if eq .CVLengthClass "cv-long"}}checked{{end}}
|
||||
hx-post="/toggle/length"
|
||||
hx-target=".cv-paper"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-indicator="#loading">
|
||||
hx-post="/toggle/length?lang={{.Lang}}"
|
||||
hx-target="#mobile-length-toggle"
|
||||
hx-swap="outerHTML"
|
||||
_="on htmx:afterRequest
|
||||
if my.checked
|
||||
remove .cv-short from .cv-paper
|
||||
add .cv-long to .cv-paper
|
||||
set localStorage['cv-length'] to 'long'
|
||||
else
|
||||
remove .cv-long from .cv-paper
|
||||
add .cv-short to .cv-paper
|
||||
set localStorage['cv-length'] to 'short'
|
||||
end">
|
||||
<span class="icon-toggle-slider">
|
||||
<iconify-icon icon="mdi:file-document-outline" width="16" height="16" class="icon-left"></iconify-icon>
|
||||
<iconify-icon icon="mdi:file-document-multiple-outline" width="16" height="16" class="icon-right"></iconify-icon>
|
||||
@@ -104,7 +122,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Logo toggle -->
|
||||
<div class="menu-control-item">
|
||||
<div class="menu-control-item" id="mobile-logo-toggle">
|
||||
<label class="menu-control-label">
|
||||
<iconify-icon icon="mdi:image-multiple-outline" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Logos{{else}}Logos{{end}}</span>
|
||||
@@ -113,10 +131,17 @@
|
||||
<input type="checkbox"
|
||||
id="logoToggleMenu"
|
||||
{{if .ShowLogos}}checked{{end}}
|
||||
hx-post="/toggle/logos"
|
||||
hx-target=".cv-paper"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-indicator="#loading">
|
||||
hx-post="/toggle/logos?lang={{.Lang}}"
|
||||
hx-target="#mobile-logo-toggle"
|
||||
hx-swap="outerHTML"
|
||||
_="on htmx:afterRequest
|
||||
if my.checked
|
||||
add .show-logos to .cv-paper
|
||||
set localStorage['cv-logos'] to 'true'
|
||||
else
|
||||
remove .show-logos from .cv-paper
|
||||
set localStorage['cv-logos'] to 'false'
|
||||
end">
|
||||
<span class="icon-toggle-slider">
|
||||
<iconify-icon icon="mdi:image-off-outline" width="16" height="16" class="icon-left"></iconify-icon>
|
||||
<iconify-icon icon="mdi:image-multiple-outline" width="16" height="16" class="icon-right"></iconify-icon>
|
||||
@@ -125,7 +150,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Theme toggle -->
|
||||
<div class="menu-control-item">
|
||||
<div class="menu-control-item" id="mobile-theme-toggle">
|
||||
<label class="menu-control-label">
|
||||
<iconify-icon icon="mdi:page-layout-sidebar-left" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Vista{{else}}View{{end}}</span>
|
||||
@@ -134,10 +159,17 @@
|
||||
<input type="checkbox"
|
||||
id="themeToggleMenu"
|
||||
{{if .ThemeClean}}checked{{end}}
|
||||
hx-post="/toggle/theme"
|
||||
hx-target="body"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-indicator="#loading">
|
||||
hx-post="/toggle/theme?lang={{.Lang}}"
|
||||
hx-target="#mobile-theme-toggle"
|
||||
hx-swap="outerHTML"
|
||||
_="on htmx:afterRequest
|
||||
if my.checked
|
||||
add .theme-clean to the body
|
||||
set localStorage['cv-theme'] to 'clean'
|
||||
else
|
||||
remove .theme-clean from the body
|
||||
set localStorage['cv-theme'] to 'default'
|
||||
end">
|
||||
<span class="icon-toggle-slider">
|
||||
<iconify-icon icon="mdi:page-layout-sidebar-left" width="16" height="16" class="icon-left"></iconify-icon>
|
||||
<iconify-icon icon="mdi:page-layout-body" width="16" height="16" class="icon-right"></iconify-icon>
|
||||
@@ -158,34 +190,7 @@
|
||||
<span>{{if eq .Lang "es"}}Descargar como PDF{{else}}Download as PDF{{end}}</span>
|
||||
</button>
|
||||
|
||||
<button class="menu-action-btn"
|
||||
_="on click
|
||||
-- Store current state
|
||||
set wasClean to .cv-container.classList.contains('theme-clean')
|
||||
set wasLong to .cv-paper.classList.contains('cv-long')
|
||||
set currentZoom to localStorage.getItem('cv-zoom') or '100'
|
||||
|
||||
-- Apply print-friendly settings
|
||||
if not wasClean then add .theme-clean to .cv-container end
|
||||
remove .cv-long from .cv-paper
|
||||
add .cv-short to .cv-paper
|
||||
set #zoom-wrapper's *zoom to 1
|
||||
|
||||
-- Print and restore
|
||||
wait 50ms
|
||||
call window.print()
|
||||
wait 100ms
|
||||
|
||||
-- Restore original state
|
||||
if not wasClean then remove .theme-clean from .cv-container end
|
||||
if wasLong
|
||||
remove .cv-short from .cv-paper
|
||||
add .cv-long to .cv-paper
|
||||
end
|
||||
if currentZoom !== '100'
|
||||
set #zoom-slider's value to currentZoom
|
||||
send input to #zoom-slider
|
||||
end">
|
||||
<button class="menu-action-btn" _="on click call printFriendly()">
|
||||
<iconify-icon icon="mdi:leaf" width="20" height="20"></iconify-icon>
|
||||
<span>{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
{{define "language-selector"}}
|
||||
<!-- Language selector -->
|
||||
<div class="language-selector">
|
||||
<!-- Language selector with atomic updates via out-of-band swaps -->
|
||||
<div class="language-selector" id="language-selector">
|
||||
<button class="selector-btn {{if eq .Lang "en"}}active{{end}}"
|
||||
data-short="EN"
|
||||
hx-get="/?lang=en"
|
||||
hx-target="body"
|
||||
hx-get="/switch-language?lang=en"
|
||||
hx-target="#language-selector"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="#loading"
|
||||
hx-push-url="true"
|
||||
hx-push-url="/?lang=en"
|
||||
aria-label="English">
|
||||
English
|
||||
</button>
|
||||
<button class="selector-btn {{if eq .Lang "es"}}active{{end}}"
|
||||
data-short="ES"
|
||||
hx-get="/?lang=es"
|
||||
hx-target="body"
|
||||
hx-get="/switch-language?lang=es"
|
||||
hx-target="#language-selector"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="#loading"
|
||||
hx-push-url="true"
|
||||
hx-push-url="/?lang=es"
|
||||
aria-label="Español">
|
||||
Español
|
||||
</button>
|
||||
|
||||
@@ -2,16 +2,25 @@
|
||||
<!-- Center: View controls with labels -->
|
||||
<div class="view-controls-center">
|
||||
<!-- CV Length toggle -->
|
||||
<div class="selector-group">
|
||||
<div class="selector-group" id="desktop-length-toggle">
|
||||
<label class="selector-label">{{if eq .Lang "es"}}Longitud{{else}}Length{{end}}:</label>
|
||||
<label class="icon-toggle">
|
||||
<input type="checkbox"
|
||||
id="lengthToggle"
|
||||
{{if eq .CVLengthClass "cv-long"}}checked{{end}}
|
||||
hx-post="/toggle/length"
|
||||
hx-target=".cv-paper"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-indicator="#loading">
|
||||
hx-post="/toggle/length?lang={{.Lang}}"
|
||||
hx-target="#desktop-length-toggle"
|
||||
hx-swap="outerHTML"
|
||||
_="on htmx:afterRequest
|
||||
if my.checked
|
||||
remove .cv-short from .cv-paper
|
||||
add .cv-long to .cv-paper
|
||||
set localStorage['cv-length'] to 'long'
|
||||
else
|
||||
remove .cv-long from .cv-paper
|
||||
add .cv-short to .cv-paper
|
||||
set localStorage['cv-length'] to 'short'
|
||||
end">
|
||||
<span class="icon-toggle-slider">
|
||||
<iconify-icon icon="mdi:file-document-outline" width="16" height="16" class="icon-left"></iconify-icon>
|
||||
<iconify-icon icon="mdi:file-document-multiple-outline" width="16" height="16" class="icon-right"></iconify-icon>
|
||||
@@ -20,16 +29,23 @@
|
||||
</div>
|
||||
|
||||
<!-- Logo toggle -->
|
||||
<div class="selector-group">
|
||||
<div class="selector-group" id="desktop-logo-toggle">
|
||||
<label class="selector-label">{{if eq .Lang "es"}}Logos{{else}}Logos{{end}}:</label>
|
||||
<label class="icon-toggle">
|
||||
<input type="checkbox"
|
||||
id="logoToggle"
|
||||
{{if .ShowLogos}}checked{{end}}
|
||||
hx-post="/toggle/logos"
|
||||
hx-target=".cv-paper"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-indicator="#loading">
|
||||
hx-post="/toggle/logos?lang={{.Lang}}"
|
||||
hx-target="#desktop-logo-toggle"
|
||||
hx-swap="outerHTML"
|
||||
_="on htmx:afterRequest
|
||||
if my.checked
|
||||
add .show-logos to .cv-paper
|
||||
set localStorage['cv-logos'] to 'true'
|
||||
else
|
||||
remove .show-logos from .cv-paper
|
||||
set localStorage['cv-logos'] to 'false'
|
||||
end">
|
||||
<span class="icon-toggle-slider">
|
||||
<iconify-icon icon="mdi:image-off-outline" width="16" height="16" class="icon-left"></iconify-icon>
|
||||
<iconify-icon icon="mdi:image-multiple-outline" width="16" height="16" class="icon-right"></iconify-icon>
|
||||
@@ -38,16 +54,23 @@
|
||||
</div>
|
||||
|
||||
<!-- Theme toggle -->
|
||||
<div class="selector-group">
|
||||
<div class="selector-group" id="desktop-theme-toggle">
|
||||
<label class="selector-label">{{if eq .Lang "es"}}Vista{{else}}View{{end}}:</label>
|
||||
<label class="icon-toggle">
|
||||
<input type="checkbox"
|
||||
id="themeToggle"
|
||||
{{if .ThemeClean}}checked{{end}}
|
||||
hx-post="/toggle/theme"
|
||||
hx-target="body"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-indicator="#loading">
|
||||
hx-post="/toggle/theme?lang={{.Lang}}"
|
||||
hx-target="#desktop-theme-toggle"
|
||||
hx-swap="outerHTML"
|
||||
_="on htmx:afterRequest
|
||||
if my.checked
|
||||
add .theme-clean to the body
|
||||
set localStorage['cv-theme'] to 'clean'
|
||||
else
|
||||
remove .theme-clean from the body
|
||||
set localStorage['cv-theme'] to 'default'
|
||||
end">
|
||||
<span class="icon-toggle-slider">
|
||||
<iconify-icon icon="mdi:page-layout-sidebar-left" width="16" height="16" class="icon-left"></iconify-icon>
|
||||
<iconify-icon icon="mdi:page-layout-body" width="16" height="16" class="icon-right"></iconify-icon>
|
||||
|
||||
Reference in New Issue
Block a user