package handlers import ( "encoding/json" "log" "net/http" "github.com/juanatsap/cv-site/internal/models" ) // CmdKAction represents a single action for the ninja-keys command palette type CmdKAction struct { ID string `json:"id"` Title string `json:"title"` Section string `json:"section"` Keywords string `json:"keywords"` } // CmdKResponse represents the response for the CMD+K API endpoint type CmdKResponse struct { Experiences []CmdKAction `json:"experiences"` Projects []CmdKAction `json:"projects"` Courses []CmdKAction `json:"courses"` } // CmdKData returns JSON data for the ninja-keys command palette // This endpoint provides dynamic entries for experiences, projects, and courses // that can be searched via CMD+K func (h *CVHandler) CmdKData(w http.ResponseWriter, r *http.Request) { // Get language from query parameter, default to "en" lang := r.URL.Query().Get("lang") if lang == "" { lang = "en" } if lang != "en" && lang != "es" { lang = "en" } // Load CV data cv, err := models.LoadCV(lang) if err != nil { log.Printf("ERROR loading CV data: %v", err) http.Error(w, "Failed to load CV data", http.StatusInternalServerError) return } // Build response response := CmdKResponse{ Experiences: make([]CmdKAction, 0, len(cv.Experience)), Projects: make([]CmdKAction, 0, len(cv.Projects)), Courses: make([]CmdKAction, 0, len(cv.Courses)), } // Map experiences for _, exp := range cv.Experience { if exp.CompanyID == "" { continue // Skip entries without ID } response.Experiences = append(response.Experiences, CmdKAction{ ID: "exp-" + exp.CompanyID, Title: exp.Company, Section: "Experience", Keywords: exp.Company + " " + exp.Position, }) } // Map projects for _, proj := range cv.Projects { if proj.ProjectID == "" { continue // Skip entries without ID } title := proj.ProjectName if title == "" { title = proj.Title } response.Projects = append(response.Projects, CmdKAction{ ID: "proj-" + proj.ProjectID, Title: title, Section: "Projects", Keywords: title + " " + proj.ShortDescription, }) } // Map courses for _, course := range cv.Courses { if course.CourseID == "" { continue // Skip entries without ID } response.Courses = append(response.Courses, CmdKAction{ ID: "course-" + course.CourseID, Title: course.Title, Section: "Courses", Keywords: course.Title + " " + course.Institution, }) } // Set headers and encode response w.Header().Set("Content-Type", "application/json") w.Header().Set("Cache-Control", "public, max-age=3600") // Cache for 1 hour if err := json.NewEncoder(w).Encode(response); err != nil { log.Printf("ERROR encoding CMD+K response: %v", err) } }