package api import ( "bytes" "embed" "html/template" "net/http" "github.com/rs/zerolog" ) //go:embed templates/*.html var templatesFS embed.FS // WebHandler serves HTML pages. type WebHandler struct { templates *template.Template logger zerolog.Logger } // NewWebHandler creates a new web handler. func NewWebHandler(logger zerolog.Logger) (*WebHandler, error) { // Parse templates from embedded filesystem tmpl, err := template.ParseFS(templatesFS, "templates/*.html") if err != nil { return nil, err } return &WebHandler{ templates: tmpl, logger: logger, }, nil } // PageData holds data for page rendering. type PageData struct { Title string Page string Data any } // render executes a page template within the base layout. func (h *WebHandler) render(w http.ResponseWriter, page string, data PageData) { // First, render the page-specific content var contentBuf bytes.Buffer if err := h.templates.ExecuteTemplate(&contentBuf, page+".html", data); err != nil { h.logger.Error().Err(err).Str("page", page).Msg("failed to render page template") http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } // Now render the base template with the content w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := h.templates.ExecuteTemplate(w, "base.html", data); err != nil { h.logger.Error().Err(err).Msg("failed to render base template") http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } // HandleIndex serves the main items page. func (h *WebHandler) HandleIndex(w http.ResponseWriter, r *http.Request) { // Check if this is the root path if r.URL.Path != "/" { http.NotFound(w, r) return } data := PageData{ Title: "Items", Page: "items", } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := h.templates.ExecuteTemplate(w, "base.html", data); err != nil { h.logger.Error().Err(err).Msg("failed to render template") http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } // HandleProjectsPage serves the projects page. func (h *WebHandler) HandleProjectsPage(w http.ResponseWriter, r *http.Request) { data := PageData{ Title: "Projects", Page: "projects", } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := h.templates.ExecuteTemplate(w, "base.html", data); err != nil { h.logger.Error().Err(err).Msg("failed to render template") http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } // HandleSchemasPage serves the schemas page. func (h *WebHandler) HandleSchemasPage(w http.ResponseWriter, r *http.Request) { data := PageData{ Title: "Schemas", Page: "schemas", } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := h.templates.ExecuteTemplate(w, "base.html", data); err != nil { h.logger.Error().Err(err).Msg("failed to render template") http.Error(w, "Internal Server Error", http.StatusInternalServerError) } }