Files
kouiz/internal/http/handler/webui/quiz/result_page.go
2025-06-15 14:46:32 +02:00

92 lines
2.3 KiB
Go

package quiz
import (
"context"
"net/http"
httpCtx "forge.cadoles.com/wpetit/kouiz/internal/http/context"
"forge.cadoles.com/wpetit/kouiz/internal/http/handler/webui/common"
"forge.cadoles.com/wpetit/kouiz/internal/http/handler/webui/quiz/component"
"forge.cadoles.com/wpetit/kouiz/internal/store"
"github.com/a-h/templ"
"github.com/pkg/errors"
"gorm.io/gorm"
)
func (h *Handler) getResultPage(w http.ResponseWriter, r *http.Request) {
vmodel, err := h.fillResultPageVModel(r)
if err != nil {
h.handleError(w, r, errors.WithStack(err))
return
}
if vmodel.Entry == nil {
baseURL := httpCtx.BaseURL(r.Context())
http.Redirect(w, r, baseURL.String(), http.StatusTemporaryRedirect)
return
}
resultPage := component.ResultPage(*vmodel)
templ.Handler(resultPage).ServeHTTP(w, r)
}
func (h *Handler) fillResultPageVModel(r *http.Request) (*component.ResultPageVModel, error) {
vmodel := &component.ResultPageVModel{}
err := common.FillViewModel(
r.Context(), vmodel, r,
h.fillResultPagePlayer,
h.fillResultPageSelectedEntry,
)
if err != nil {
return nil, errors.WithStack(err)
}
return vmodel, nil
}
func (h *Handler) fillResultPagePlayer(ctx context.Context, vmodel *component.ResultPageVModel, r *http.Request) error {
player, err := h.getRequestPlayer(r)
if err != nil {
return errors.WithStack(err)
}
vmodel.Player = player
rank, err := h.store.GetPlayerRank(ctx, player.ID)
if err != nil {
return errors.WithStack(err)
}
vmodel.PlayerRank = rank
return nil
}
func (h *Handler) fillResultPageSelectedEntry(ctx context.Context, vmodel *component.ResultPageVModel, r *http.Request) error {
if vmodel.Player == nil || vmodel.Player.SelectedEntry == nil {
return nil
}
var entry *store.QuizEntry
err := h.store.Do(ctx, func(db *gorm.DB) error {
err := db.Model(&entry).Preload("Category").First(&entry, "id = ?", vmodel.Player.SelectedEntry).Error
if err != nil {
return errors.WithStack(err)
}
return nil
})
if err != nil {
return errors.WithStack(err)
}
vmodel.Entry = entry
if vmodel.Player.SelectedAnswer != nil && *vmodel.Player.SelectedAnswer >= 0 && *vmodel.Player.SelectedAnswer < len(entry.Propositions) {
selectedAnswer := entry.Propositions[*vmodel.Player.SelectedAnswer]
vmodel.Won = selectedAnswer == entry.Answer
}
return nil
}