package handlers import ( "log/slog" "net/http" "qbank/internal/auth" "qbank/internal/db" "qbank/internal/models" ) // QuestionRow pairs a question with its per-user stat for the library display. type QuestionRow struct { Q *models.Question Stat *models.UserQuestionStat // nil = never seen in a test } type HomeHandler struct { auth *auth.Manager repo *db.Repo render *Renderer } func NewHomeHandler(a *auth.Manager, repo *db.Repo, r *Renderer) *HomeHandler { return &HomeHandler{auth: a, repo: repo, render: r} } func (h *HomeHandler) Handle(w http.ResponseWriter, r *http.Request) { user := auth.UserFromCtx(r.Context()) sortParam := r.URL.Query().Get("sort") search := r.URL.Query().Get("q") source := r.URL.Query().Get("source") var sortOrder db.SortOrder switch sortParam { case "weakest": sortOrder = db.SortWeakest case "seen": sortOrder = db.SortMostSeen default: sortParam = "alpha" sortOrder = db.SortAlpha } questions, err := h.repo.ListQuestions(db.ListFilter{ Source: source, Search: search, Sort: sortOrder, UserID: user.ID, }) if err != nil { slog.Error("list questions", "err", err) HTTPError(w, http.StatusInternalServerError) return } ids := make([]string, len(questions)) for i, q := range questions { ids[i] = q.ID } stats, err := h.repo.GetStatsForUser(user.ID, ids) if err != nil { slog.Error("get stats", "err", err) HTTPError(w, http.StatusInternalServerError) return } rows := make([]QuestionRow, len(questions)) for i, q := range questions { rows[i] = QuestionRow{Q: q, Stat: stats[q.ID]} } totalQ, _ := h.repo.CountQuestions() totalA, _ := h.repo.CountAnswers() sourceCounts, _ := h.repo.CountBySource() data := BaseData(h.auth, r) data["Questions"] = rows data["TotalQ"] = totalQ data["TotalA"] = totalA data["SourceStats"] = sourceCounts data["Sort"] = sortParam data["Search"] = search data["SelectedSource"] = source h.render.Render(w, http.StatusOK, "home", data) }