package api import ( "fmt" "html/template" "log" "net/http" "strings" "time" authpkg "jiggablend/internal/auth" "jiggablend/web" ) type uiRenderer struct { templates *template.Template } type pageData struct { Title string CurrentPath string ContentTemplate string PageScript string User *authpkg.Session Error string Notice string Data interface{} } func newUIRenderer() (*uiRenderer, error) { tpl, err := template.New("base").Funcs(template.FuncMap{ "formatTime": func(t time.Time) string { if t.IsZero() { return "-" } return t.Local().Format("2006-01-02 15:04:05") }, "statusClass": func(status string) string { switch status { case "completed": return "status-completed" case "running": return "status-running" case "failed": return "status-failed" case "cancelled": return "status-cancelled" case "online": return "status-online" case "offline": return "status-offline" case "busy": return "status-busy" default: return "status-pending" } }, "progressInt": func(v float64) int { if v < 0 { return 0 } if v > 100 { return 100 } return int(v) }, "derefInt": func(v *int) string { if v == nil { return "" } return fmt.Sprintf("%d", *v) }, "derefString": func(v *string) string { if v == nil { return "" } return *v }, "hasSuffixFold": func(value, suffix string) bool { return strings.HasSuffix(strings.ToLower(value), strings.ToLower(suffix)) }, }).ParseFS( web.GetTemplateFS(), "templates/*.html", "templates/partials/*.html", ) if err != nil { return nil, fmt.Errorf("parse templates: %w", err) } return &uiRenderer{templates: tpl}, nil } func (r *uiRenderer) render(w http.ResponseWriter, data pageData) { w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := r.templates.ExecuteTemplate(w, "base", data); err != nil { log.Printf("Template render error: %v", err) http.Error(w, "template render error", http.StatusInternalServerError) return } } func (r *uiRenderer) renderTemplate(w http.ResponseWriter, templateName string, data interface{}) { w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := r.templates.ExecuteTemplate(w, templateName, data); err != nil { log.Printf("Template render error for %s: %v", templateName, err) http.Error(w, "template render error", http.StatusInternalServerError) return } }