go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/kana-server/pkg/controller/home.go (about)

     1  /*
     2  
     3  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package controller
     9  
    10  import (
    11  	"net/http"
    12  	"time"
    13  
    14  	"go.charczuk.com/sdk/apputil"
    15  	"go.charczuk.com/sdk/uuid"
    16  	"go.charczuk.com/sdk/web"
    17  
    18  	"go.charczuk.com/projects/kana-server/pkg/config"
    19  	"go.charczuk.com/projects/kana-server/pkg/model"
    20  	"go.charczuk.com/projects/kana-server/pkg/types"
    21  )
    22  
    23  // Home is the home controller.
    24  type Home struct {
    25  	apputil.BaseController
    26  
    27  	Config config.Config
    28  	Model  model.Manager
    29  }
    30  
    31  // Register regisers the controller.
    32  func (h Home) Register(app *web.App) {
    33  	app.Get("/home", web.SessionRequired(h.home))
    34  	app.Get("/home/:id", web.SessionRequired(h.homeQuizStats))
    35  }
    36  
    37  // GET /stats
    38  func (h Home) home(ctx web.Context) web.Result {
    39  	userID := h.GetUserID(ctx)
    40  	all, err := h.Model.AllQuzzes(ctx, userID)
    41  	if err != nil {
    42  		return ctx.App().Views.InternalError(err)
    43  	}
    44  	return ctx.App().Views.ViewStatus(http.StatusOK, "home", CreateHomeViewModel(all))
    45  }
    46  
    47  // GET /home/:id
    48  func (h Home) homeQuizStats(ctx web.Context) web.Result {
    49  	userID := h.GetUserID(ctx)
    50  	rawID, _ := ctx.RouteParams().Get("id")
    51  	quizID, err := uuid.Parse(rawID)
    52  	if err != nil {
    53  		return ctx.App().Views.BadRequest(err)
    54  	}
    55  	quiz, found, err := h.Model.GetQuiz(ctx, quizID)
    56  	if err != nil {
    57  		return ctx.App().Views.InternalError(err)
    58  	}
    59  	if !found || !quiz.UserID.Equal(userID) {
    60  		return ctx.App().Views.NotFound()
    61  	}
    62  	return ctx.App().Views.ViewStatus(http.StatusOK, "home_quiz_stats", quiz)
    63  }
    64  
    65  // CreateHomeViewModel creates a home view model.
    66  func CreateHomeViewModel(all []*types.Quiz) (hvm HomeViewModel) {
    67  	hvm.TotalQuizzes = len(all)
    68  	for _, q := range all {
    69  		hvm.TotalQuizResults += len(q.Results)
    70  		for _, qr := range q.Results {
    71  			if qr.Correct() {
    72  				hvm.TotalQuizResultsCorrect++
    73  			}
    74  			hvm.TotalQuizDuration += qr.Elapsed()
    75  		}
    76  	}
    77  	hvm.Quizzes = all
    78  	return
    79  }
    80  
    81  // HomeViewModel is the viewmodel for the home page.
    82  type HomeViewModel struct {
    83  	TotalQuizzes            int
    84  	TotalQuizResults        int
    85  	TotalQuizResultsCorrect int
    86  	TotalQuizDuration       time.Duration
    87  	Quizzes                 []*types.Quiz
    88  }
    89  
    90  // TotalQuizCorrectPct returns the percentage of results correct.
    91  func (hvm HomeViewModel) TotalQuizCorrectPct() float64 {
    92  	if hvm.TotalQuizResults == 0 {
    93  		return 0
    94  	}
    95  	return (float64(hvm.TotalQuizResultsCorrect) / float64(hvm.TotalQuizResults)) * 100.0
    96  }