more htmx
This commit is contained in:
+75
-44
@@ -662,7 +662,7 @@ func setPreferenceCookie(w http.ResponseWriter, name string, value string) {
|
||||
})
|
||||
}
|
||||
|
||||
// ToggleLength handles CV length toggle (short/long)
|
||||
// ToggleLength handles CV length toggle (short/long) using atomic out-of-band swaps
|
||||
func (h *CVHandler) ToggleLength(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
@@ -671,7 +671,7 @@ func (h *CVHandler) ToggleLength(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Get current state
|
||||
currentLength := getPreferenceCookie(r, "cv-length", "short")
|
||||
|
||||
|
||||
// Toggle state
|
||||
newLength := "long"
|
||||
if currentLength == "long" {
|
||||
@@ -687,39 +687,32 @@ func (h *CVHandler) ToggleLength(w http.ResponseWriter, r *http.Request) {
|
||||
lang = getPreferenceCookie(r, "cv-language", "en")
|
||||
}
|
||||
|
||||
// Prepare template data
|
||||
data, err := h.prepareTemplateData(lang)
|
||||
if err != nil {
|
||||
HandleError(w, r, DataLoadError(err, "CV"))
|
||||
return
|
||||
}
|
||||
|
||||
// Add length class to data
|
||||
// Prepare template data with length state
|
||||
cvLengthClass := "cv-short"
|
||||
if newLength == "long" {
|
||||
data["CVLengthClass"] = "cv-long"
|
||||
} else {
|
||||
data["CVLengthClass"] = "cv-short"
|
||||
cvLengthClass = "cv-long"
|
||||
}
|
||||
|
||||
// Also read and preserve logo preference
|
||||
cvLogos := getPreferenceCookie(r, "cv-logos", "show")
|
||||
data["ShowLogos"] = (cvLogos == "show")
|
||||
data := map[string]interface{}{
|
||||
"Lang": lang,
|
||||
"CVLengthClass": cvLengthClass,
|
||||
}
|
||||
|
||||
// Render cv-content template
|
||||
tmpl, err := h.templates.Render("cv-content.html")
|
||||
// Render length-toggle template with out-of-band swaps
|
||||
tmpl, err := h.templates.Render("length-toggle.html")
|
||||
if err != nil {
|
||||
HandleError(w, r, TemplateError(err, "cv-content.html"))
|
||||
HandleError(w, r, TemplateError(err, "length-toggle.html"))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := tmpl.Execute(w, data); err != nil {
|
||||
HandleError(w, r, TemplateError(err, "cv-content.html"))
|
||||
HandleError(w, r, TemplateError(err, "length-toggle.html"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ToggleLogos handles logo visibility toggle
|
||||
// ToggleLogos handles logo visibility toggle using atomic out-of-band swaps
|
||||
func (h *CVHandler) ToggleLogos(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
@@ -728,7 +721,7 @@ func (h *CVHandler) ToggleLogos(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Get current state
|
||||
currentLogos := getPreferenceCookie(r, "cv-logos", "show")
|
||||
|
||||
|
||||
// Toggle state
|
||||
newLogos := "hide"
|
||||
if currentLogos == "hide" {
|
||||
@@ -744,6 +737,45 @@ func (h *CVHandler) ToggleLogos(w http.ResponseWriter, r *http.Request) {
|
||||
lang = getPreferenceCookie(r, "cv-language", "en")
|
||||
}
|
||||
|
||||
// Prepare template data with logo state
|
||||
data := map[string]interface{}{
|
||||
"Lang": lang,
|
||||
"ShowLogos": (newLogos == "show"),
|
||||
}
|
||||
|
||||
// Render logo-toggle template with out-of-band swaps
|
||||
tmpl, err := h.templates.Render("logo-toggle.html")
|
||||
if err != nil {
|
||||
HandleError(w, r, TemplateError(err, "logo-toggle.html"))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := tmpl.Execute(w, data); err != nil {
|
||||
HandleError(w, r, TemplateError(err, "logo-toggle.html"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// SwitchLanguage handles language switching with atomic updates
|
||||
// Uses HTMX out-of-band swaps to update both the language selector buttons
|
||||
// and all CV content wrappers in a single response
|
||||
func (h *CVHandler) SwitchLanguage(w http.ResponseWriter, r *http.Request) {
|
||||
// Get language from query parameter
|
||||
lang := r.URL.Query().Get("lang")
|
||||
if lang == "" {
|
||||
lang = "en"
|
||||
}
|
||||
|
||||
// Validate language
|
||||
if lang != "en" && lang != "es" {
|
||||
HandleError(w, r, BadRequestError("Unsupported language. Use 'en' or 'es'"))
|
||||
return
|
||||
}
|
||||
|
||||
// Save language preference
|
||||
setPreferenceCookie(w, "cv-language", lang)
|
||||
|
||||
// Prepare template data
|
||||
data, err := h.prepareTemplateData(lang)
|
||||
if err != nil {
|
||||
@@ -751,32 +783,35 @@ func (h *CVHandler) ToggleLogos(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Add logos class to data
|
||||
data["ShowLogos"] = (newLogos == "show")
|
||||
|
||||
// Also read and preserve length preference
|
||||
// Preserve current length and logo preferences
|
||||
cvLength := getPreferenceCookie(r, "cv-length", "short")
|
||||
cvLogos := getPreferenceCookie(r, "cv-logos", "show")
|
||||
cvTheme := getPreferenceCookie(r, "cv-theme", "default")
|
||||
|
||||
// Add preferences to data
|
||||
if cvLength == "long" {
|
||||
data["CVLengthClass"] = "cv-long"
|
||||
} else {
|
||||
data["CVLengthClass"] = "cv-short"
|
||||
}
|
||||
data["ShowLogos"] = (cvLogos == "show")
|
||||
data["ThemeClean"] = (cvTheme == "clean")
|
||||
|
||||
// Render cv-content template
|
||||
tmpl, err := h.templates.Render("cv-content.html")
|
||||
// Render language-switch template with out-of-band swaps
|
||||
tmpl, err := h.templates.Render("language-switch.html")
|
||||
if err != nil {
|
||||
HandleError(w, r, TemplateError(err, "cv-content.html"))
|
||||
HandleError(w, r, TemplateError(err, "language-switch.html"))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := tmpl.Execute(w, data); err != nil {
|
||||
HandleError(w, r, TemplateError(err, "cv-content.html"))
|
||||
HandleError(w, r, TemplateError(err, "language-switch.html"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ToggleTheme handles theme toggle (default/clean)
|
||||
// ToggleTheme handles theme toggle (default/clean) using atomic out-of-band swaps
|
||||
func (h *CVHandler) ToggleTheme(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
@@ -785,7 +820,7 @@ func (h *CVHandler) ToggleTheme(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Get current state
|
||||
currentTheme := getPreferenceCookie(r, "cv-theme", "default")
|
||||
|
||||
|
||||
// Toggle state
|
||||
newTheme := "clean"
|
||||
if currentTheme == "clean" {
|
||||
@@ -801,26 +836,22 @@ func (h *CVHandler) ToggleTheme(w http.ResponseWriter, r *http.Request) {
|
||||
lang = getPreferenceCookie(r, "cv-language", "en")
|
||||
}
|
||||
|
||||
// Prepare template data
|
||||
data, err := h.prepareTemplateData(lang)
|
||||
if err != nil {
|
||||
HandleError(w, r, DataLoadError(err, "CV"))
|
||||
return
|
||||
// Prepare template data with theme state
|
||||
data := map[string]interface{}{
|
||||
"Lang": lang,
|
||||
"ThemeClean": (newTheme == "clean"),
|
||||
}
|
||||
|
||||
// Add theme class to data
|
||||
data["ThemeClean"] = (newTheme == "clean")
|
||||
|
||||
// Render full page to update container class
|
||||
tmpl, err := h.templates.Render("index.html")
|
||||
// Render theme-toggle template with out-of-band swaps
|
||||
tmpl, err := h.templates.Render("theme-toggle.html")
|
||||
if err != nil {
|
||||
HandleError(w, r, TemplateError(err, "index.html"))
|
||||
HandleError(w, r, TemplateError(err, "theme-toggle.html"))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := tmpl.Execute(w, data); err != nil {
|
||||
HandleError(w, r, TemplateError(err, "index.html"))
|
||||
HandleError(w, r, TemplateError(err, "theme-toggle.html"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ func Setup(cvHandler *handlers.CVHandler, healthHandler *handlers.HealthHandler)
|
||||
mux.HandleFunc("/health", healthHandler.Check)
|
||||
|
||||
// HTMX endpoints for interactive controls
|
||||
mux.HandleFunc("/switch-language", cvHandler.SwitchLanguage)
|
||||
mux.HandleFunc("/toggle/length", cvHandler.ToggleLength)
|
||||
mux.HandleFunc("/toggle/logos", cvHandler.ToggleLogos)
|
||||
mux.HandleFunc("/toggle/theme", cvHandler.ToggleTheme)
|
||||
|
||||
Reference in New Issue
Block a user