package handlers import ( "net/http" "time" "git.eeqj.de/sneak/upaas/internal/models" "git.eeqj.de/sneak/upaas/templates" ) // AppStats holds deployment statistics for an app. type AppStats struct { App *models.App LastDeployTime *time.Time LastDeployISO string LastDeployLabel string DeployCount int } // HandleDashboard returns the dashboard handler. func (h *Handlers) HandleDashboard() http.HandlerFunc { tmpl := templates.GetParsed() return func(writer http.ResponseWriter, request *http.Request) { ctx := request.Context() apps, fetchErr := models.AllApps(ctx, h.db) if fetchErr != nil { h.log.Error("failed to fetch apps", "error", fetchErr) http.Error(writer, "Internal Server Error", http.StatusInternalServerError) return } // Fetch stats for each app appStats := make([]*AppStats, 0, len(apps)) for _, app := range apps { stats := &AppStats{App: app} // Get deploy count count, countErr := models.CountDeploymentsByAppID(ctx, h.db, app.ID) if countErr != nil { h.log.Error("failed to count deployments", "error", countErr, "app", app.ID) } else { stats.DeployCount = count } // Get latest deployment latest, latestErr := models.LatestDeploymentForApp(ctx, h.db, app.ID) if latestErr != nil { h.log.Error("failed to get latest deployment", "error", latestErr, "app", app.ID) } else if latest != nil { if latest.FinishedAt.Valid { stats.LastDeployTime = &latest.FinishedAt.Time stats.LastDeployISO = latest.FinishedAt.Time.Format(time.RFC3339) stats.LastDeployLabel = latest.FinishedAt.Time.Format("2006-01-02 15:04:05") } else { stats.LastDeployTime = &latest.StartedAt stats.LastDeployISO = latest.StartedAt.Format(time.RFC3339) stats.LastDeployLabel = latest.StartedAt.Format("2006-01-02 15:04:05") } } appStats = append(appStats, stats) } data := h.addGlobals(map[string]any{ "AppStats": appStats, }, request) h.renderTemplate(writer, tmpl, "dashboard.html", data) } }