aae1a28627
- Projects searchable by technologies, "open source", category (cli/app/web) - Experience searchable by technologies, shows company logo + position - Courses show institution logos - Project logos used as icons instead of generic mdi:web - Category-specific fallback icons (console, apple, puzzle, etc.)
134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
|
|
c "github.com/juanatsap/cv-site/internal/constants"
|
|
"github.com/juanatsap/cv-site/internal/httputil"
|
|
)
|
|
|
|
// 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"`
|
|
Category string `json:"category,omitempty"` // cli, app, web, plugin, sdk, contrib
|
|
Icon string `json:"icon,omitempty"` // Project logo filename
|
|
}
|
|
|
|
// 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) {
|
|
lang := httputil.Lang(r)
|
|
|
|
// Get CV data from cache
|
|
cv := h.dataCache.GetCV(lang)
|
|
if cv == nil {
|
|
log.Printf("ERROR: CV data not found in cache for language: %s", lang)
|
|
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
|
|
}
|
|
keywords := exp.Company + " " + exp.Position
|
|
for _, tech := range exp.Technologies {
|
|
keywords += " " + tech
|
|
}
|
|
keywords += " work job career"
|
|
icon := ""
|
|
if exp.CompanyLogo != "" {
|
|
icon = exp.CompanyLogo
|
|
}
|
|
response.Experiences = append(response.Experiences, CmdKAction{
|
|
ID: "exp-" + exp.CompanyID,
|
|
Title: exp.Company + " — " + exp.Position,
|
|
Section: "Experience",
|
|
Keywords: keywords,
|
|
Icon: icon,
|
|
})
|
|
}
|
|
|
|
// Map projects
|
|
for _, proj := range cv.Projects {
|
|
if proj.ProjectID == "" {
|
|
continue
|
|
}
|
|
title := proj.ProjectName
|
|
if title == "" {
|
|
title = proj.Title
|
|
}
|
|
keywords := title + " " + proj.ShortDescription
|
|
for _, tech := range proj.Technologies {
|
|
keywords += " " + tech
|
|
}
|
|
if proj.OpenSource {
|
|
keywords += " open source open-source oss github"
|
|
}
|
|
if proj.Category != "" {
|
|
keywords += " " + proj.Category
|
|
}
|
|
icon := ""
|
|
if proj.ProjectLogo != "" {
|
|
icon = proj.ProjectLogo
|
|
}
|
|
response.Projects = append(response.Projects, CmdKAction{
|
|
ID: "proj-" + proj.ProjectID,
|
|
Title: title,
|
|
Section: "Projects",
|
|
Keywords: keywords,
|
|
Category: proj.Category,
|
|
Icon: icon,
|
|
})
|
|
}
|
|
|
|
// Map courses
|
|
for _, course := range cv.Courses {
|
|
if course.CourseID == "" {
|
|
continue
|
|
}
|
|
keywords := course.Title + " " + course.Institution
|
|
keywords += " course training certification"
|
|
icon := ""
|
|
if course.CourseLogo != "" {
|
|
icon = course.CourseLogo
|
|
}
|
|
response.Courses = append(response.Courses, CmdKAction{
|
|
ID: "course-" + course.CourseID,
|
|
Title: course.Title,
|
|
Section: "Courses",
|
|
Keywords: keywords,
|
|
Icon: icon,
|
|
})
|
|
}
|
|
|
|
// Set headers and encode response
|
|
w.Header().Set(c.HeaderContentType, c.ContentTypeJSON)
|
|
w.Header().Set(c.HeaderCacheControl, c.CachePublic1Hour)
|
|
|
|
if err := json.NewEncoder(w).Encode(response); err != nil {
|
|
log.Printf("ERROR encoding CMD+K response: %v", err)
|
|
}
|
|
}
|