package web import ( "html/template" "net/http" "sort" "time" "github.com/domagojzecevic/cammonitor/internal/auth" "github.com/domagojzecevic/cammonitor/internal/footage" webtemplates "github.com/domagojzecevic/cammonitor/internal/web/templates" "github.com/go-chi/chi/v5" ) type Handler struct { index *footage.Index } type ShellData struct { Title string User *auth.User Months []MonthGroup CurrentDate string ActiveTab string Content any } type MonthGroup struct { Label string Days []string } type DayPageData struct { Date string ImageCount int VideoCount int } func NewHandler(index *footage.Index) *Handler { return &Handler{index: index} } func (h *Handler) Index(w http.ResponseWriter, r *http.Request) { days := h.dayList() if len(days) == 0 { h.render(w, r, ShellData{ Title: "CamMonitor", Content: DayPageData{ Date: "No footage", }, }) return } http.Redirect(w, r, "/day/"+days[0]+"/images", http.StatusFound) } func (h *Handler) DayOverview(w http.ResponseWriter, r *http.Request) { date := chi.URLParam(r, "date") day, ok := h.day(date) if !ok { http.NotFound(w, r) return } h.render(w, r, ShellData{ Title: "CamMonitor " + date, CurrentDate: date, Content: DayPageData{ Date: date, ImageCount: len(day.Images), VideoCount: len(day.Videos), }, }) } func (h *Handler) render(w http.ResponseWriter, r *http.Request, data ShellData) { data.User, _ = auth.UserFromContext(r.Context()) data.Months = groupDaysByMonth(h.dayList()) w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := shellTemplate.ExecuteTemplate(w, "base", data); err != nil { http.Error(w, "render page failed", http.StatusInternalServerError) } } func (h *Handler) dayList() []string { if h.index == nil { return nil } return h.index.DayList() } func (h *Handler) day(date string) (*footage.DayEntry, bool) { if h.index == nil { return nil, false } return h.index.Day(date) } func groupDaysByMonth(days []string) []MonthGroup { groups := make(map[string][]string) labels := make([]string, 0) for _, day := range days { if len(day) != len("20060102") { continue } parsed, err := time.Parse("20060102", day) if err != nil { continue } label := parsed.Format("2006-01") if _, ok := groups[label]; !ok { labels = append(labels, label) } groups[label] = append(groups[label], day) } sort.Sort(sort.Reverse(sort.StringSlice(labels))) monthGroups := make([]MonthGroup, 0, len(labels)) for _, label := range labels { monthGroups = append(monthGroups, MonthGroup{ Label: label, Days: groups[label], }) } return monthGroups } var shellTemplate = template.Must(template.ParseFS( webtemplates.FS, webtemplates.Base, webtemplates.Day, ))