From 8392a764a20cd66eb9fa7e8c583a036ee144441c Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Thu, 10 Jul 2025 19:55:46 +0300 Subject: [PATCH] Feat: stats [WIP] --- components/base.html | 2 +- components/index.html | 4 ++- components/stats.html | 83 +++++++++++++++++++++++++++++++++++++++++++ handlers/handlers.go | 39 ++++++++++++++++++++ main.go | 1 + repos/player_stats.go | 7 ++++ 6 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 components/stats.html diff --git a/components/base.html b/components/base.html index 817edf6..433ae11 100644 --- a/components/base.html +++ b/components/base.html @@ -43,7 +43,7 @@
- {{template "main" .}} + {{template "main" .}}
diff --git a/components/index.html b/components/index.html index f0bb91d..80698b5 100644 --- a/components/index.html +++ b/components/index.html @@ -5,9 +5,11 @@ {{template "linklogin" .LinkLogin}} {{ else if not .State.RoomID }}
-

Hello {{.State.Username}}

diff --git a/components/stats.html b/components/stats.html new file mode 100644 index 0000000..6e8f018 --- /dev/null +++ b/components/stats.html @@ -0,0 +1,83 @@ +{{define "stats"}} + + + + Alias + + + + + + + + + + +
+
+

Player Leaderboard

+ +
+ + + + + + + + + + + + + {{range .}} + + + + + + + + + {{end}} + +
PlayerGames PlayedGames WonGames LostMime WinrateGuesser Winrate
{{.PlayerUsername}}{{.GamesPlayed}}{{.GamesWon}}{{.GamesLost}}{{printf "%.2f" .MimeWinrate}}{{printf "%.2f" .GuesserWinrate}}
+
+
+
+ + +{{end}} diff --git a/handlers/handlers.go b/handlers/handlers.go index b2df877..2a34edd 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -113,3 +113,42 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { log.Error("failed to exec templ;", "error", err, "templ", "base") } } + +func HandleStats(w http.ResponseWriter, r *http.Request) { + log.Debug("got stats call") + tmpl, err := template.ParseGlob("components/*.html") + if err != nil { + abortWithError(w, err.Error()) + return + } + stats, err := repo.GetAllPlayerStats(r.Context()) + if err != nil { + log.Error("failed to get all player stats", "error", err) + abortWithError(w, "failed to retrieve player stats") + return + } + fi, err := getFullInfoByCtx(r.Context()) + if err != nil { + log.Error("failed to fetch fi", "error", err) + } + // there must be a better way + if fi != nil && fi.Room != nil && fi.Room.ID != "" && fi.State != nil { + fi.Room.UpdateCounter() + if fi.State.Role == "mime" { + fi.Room.MimeView() // there must be a better way + } else { + fi.Room.GuesserView() + } + } + if fi != nil && fi.Room == nil { + rooms, err := repo.RoomList(r.Context()) + if err != nil { + log.Error("failed to list rooms;", "error", err) + } + fi.List = rooms + } + fi.List = nil + if err := tmpl.ExecuteTemplate(w, "stats", stats); err != nil { + log.Error("failed to exec templ;", "error", err, "templ", "base") + } +} diff --git a/main.go b/main.go index 0dadf22..290d995 100644 --- a/main.go +++ b/main.go @@ -68,6 +68,7 @@ func ListenToRequests(port string) *http.Server { // mux.HandleFunc("GET /ping", handlers.HandlePing) mux.HandleFunc("GET /", handlers.HandleHome) + mux.HandleFunc("GET /stats", handlers.HandleStats) mux.HandleFunc("POST /login", handlers.HandleFrontLogin) mux.HandleFunc("GET /signout", handlers.HandleSignout) mux.HandleFunc("POST /join-team", handlers.HandleJoinTeam) diff --git a/repos/player_stats.go b/repos/player_stats.go index 4ee5d1f..a4cab6d 100644 --- a/repos/player_stats.go +++ b/repos/player_stats.go @@ -9,6 +9,7 @@ import ( type PlayerStatsRepo interface { GetPlayerStats(ctx context.Context, username string) (*models.PlayerStats, error) + GetAllPlayerStats(ctx context.Context) ([]*models.PlayerStats, error) UpdatePlayerStats(ctx context.Context, stats *models.PlayerStats) error CreatePlayerStats(ctx context.Context, username string) error } @@ -19,6 +20,12 @@ func (p *RepoProvider) GetPlayerStats(ctx context.Context, username string) (*mo return stats, err } +func (p *RepoProvider) GetAllPlayerStats(ctx context.Context) ([]*models.PlayerStats, error) { + var stats []*models.PlayerStats + err := sqlx.SelectContext(ctx, p.DB, &stats, "SELECT * FROM player_stats ORDER BY games_won DESC") + return stats, err +} + func (p *RepoProvider) UpdatePlayerStats(ctx context.Context, stats *models.PlayerStats) error { _, err := p.DB.NamedExecContext(ctx, `UPDATE player_stats SET games_played = :games_played,