package web import ( "embed" "fmt" "html/template" "net/http" "naviwatcher/internal/config" "naviwatcher/internal/database" ) //go:embed templates/*.html var templates embed.FS // dashboardTmpl is parsed once at package init from the embedded templates. var dashboardTmpl = template.Must(template.ParseFS(templates, "templates/dashboard.html")) // handleDashboard renders the artist dashboard: monitored artists with their // missing-release counts. func (s *Server) handleDashboard(w http.ResponseWriter, r *http.Request) { // Only serve the index at "/" (and not e.g. "/favicon.ico" fallthroughs). if r.URL.Path != "/" { http.NotFound(w, r) return } threshold := s.defaultThreshold() data, err := s.buildDashboardData(r.Context(), threshold) if err != nil { http.Error(w, fmt.Sprintf("failed to build dashboard: %v", err), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := dashboardTmpl.Execute(w, data); err != nil { http.Error(w, fmt.Sprintf("template render error: %v", err), http.StatusInternalServerError) } } // defaultThreshold returns the fuzzy threshold to use when scanning for the // dashboard. It is currently fixed at the engine default; later wiring can // thread the configured threshold through the Server if desired. func (s *Server) defaultThreshold() float64 { return 0 // 0 → scanner.DefaultThreshold } // NewServerWithConfig is a convenience constructor that accepts the full // *config.Config (mirroring how the app constructs other components). It // forwards the server sub-config and derives uiBaseURL from host/port. func NewServerWithConfig(cfg *config.Config, db *database.DB) *Server { // Build a best-effort external base URL from the server config. base := fmt.Sprintf("http://%s:%d", cfg.Server.Host, cfg.Server.Port) return NewServer(&cfg.Server, db, base) }