mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
refactor: use query param for leaderboard controls
This commit is contained in:
parent
b3fa032bde
commit
1d7ff4bc2a
@ -3,12 +3,12 @@ package view
|
|||||||
import "github.com/muety/wakapi/models"
|
import "github.com/muety/wakapi/models"
|
||||||
|
|
||||||
type LeaderboardViewModel struct {
|
type LeaderboardViewModel struct {
|
||||||
User *models.User
|
User *models.User
|
||||||
Items []*models.LeaderboardItem
|
By string
|
||||||
ItemsByLanguage []*models.LeaderboardItem
|
Items []*models.LeaderboardItem
|
||||||
ApiKey string
|
ApiKey string
|
||||||
Success string
|
Success string
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LeaderboardViewModel) WithSuccess(m string) *LeaderboardViewModel {
|
func (s *LeaderboardViewModel) WithSuccess(m string) *LeaderboardViewModel {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
conf "github.com/muety/wakapi/config"
|
conf "github.com/muety/wakapi/config"
|
||||||
"github.com/muety/wakapi/middlewares"
|
"github.com/muety/wakapi/middlewares"
|
||||||
@ -8,6 +9,7 @@ import (
|
|||||||
"github.com/muety/wakapi/models/view"
|
"github.com/muety/wakapi/models/view"
|
||||||
"github.com/muety/wakapi/services"
|
"github.com/muety/wakapi/services"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LeaderboardHandler struct {
|
type LeaderboardHandler struct {
|
||||||
@ -16,6 +18,10 @@ type LeaderboardHandler struct {
|
|||||||
leaderboardService services.ILeaderboardService
|
leaderboardService services.ILeaderboardService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allowedAggregations = map[string]uint8{
|
||||||
|
"language": models.SummaryLanguage,
|
||||||
|
}
|
||||||
|
|
||||||
func NewLeaderboardHandler(userService services.IUserService, leaderboardService services.ILeaderboardService) *LeaderboardHandler {
|
func NewLeaderboardHandler(userService services.IUserService, leaderboardService services.ILeaderboardService) *LeaderboardHandler {
|
||||||
return &LeaderboardHandler{
|
return &LeaderboardHandler{
|
||||||
config: conf.Get(),
|
config: conf.Get(),
|
||||||
@ -44,18 +50,27 @@ func (h *LeaderboardHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func (h *LeaderboardHandler) buildViewModel(r *http.Request) *view.LeaderboardViewModel {
|
func (h *LeaderboardHandler) buildViewModel(r *http.Request) *view.LeaderboardViewModel {
|
||||||
user := middlewares.GetPrincipal(r)
|
user := middlewares.GetPrincipal(r)
|
||||||
|
byParam := strings.ToLower(r.URL.Query().Get("by"))
|
||||||
|
|
||||||
itemsGeneral, err := h.leaderboardService.GetByInterval(models.IntervalPast7Days)
|
var err error
|
||||||
if err != nil {
|
var items []*models.LeaderboardItem
|
||||||
conf.Log().Request(r).Error("error while fetching general leaderboard items - %v", err)
|
|
||||||
return &view.LeaderboardViewModel{Error: criticalError}
|
|
||||||
}
|
|
||||||
|
|
||||||
by := models.SummaryLanguage
|
if byParam == "" {
|
||||||
itemsByLanguage, err := h.leaderboardService.GetAggregatedByInterval(models.IntervalPast7Days, &by)
|
items, err = h.leaderboardService.GetByInterval(models.IntervalPast7Days)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conf.Log().Request(r).Error("error while fetching general leaderboard items - %v", err)
|
conf.Log().Request(r).Error("error while fetching general leaderboard items - %v", err)
|
||||||
return &view.LeaderboardViewModel{Error: criticalError}
|
return &view.LeaderboardViewModel{Error: criticalError}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if by, ok := allowedAggregations[byParam]; ok {
|
||||||
|
items, err = h.leaderboardService.GetAggregatedByInterval(models.IntervalPast7Days, &by)
|
||||||
|
if err != nil {
|
||||||
|
conf.Log().Request(r).Error("error while fetching general leaderboard items - %v", err)
|
||||||
|
return &view.LeaderboardViewModel{Error: criticalError}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return &view.LeaderboardViewModel{Error: fmt.Sprintf("unsupported aggregation '%s'", byParam)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiKey string
|
var apiKey string
|
||||||
@ -64,11 +79,11 @@ func (h *LeaderboardHandler) buildViewModel(r *http.Request) *view.LeaderboardVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &view.LeaderboardViewModel{
|
return &view.LeaderboardViewModel{
|
||||||
User: user,
|
User: user,
|
||||||
Items: itemsGeneral,
|
By: byParam,
|
||||||
ItemsByLanguage: itemsByLanguage,
|
Items: items,
|
||||||
ApiKey: apiKey,
|
ApiKey: apiKey,
|
||||||
Success: r.URL.Query().Get("success"),
|
Success: r.URL.Query().Get("success"),
|
||||||
Error: r.URL.Query().Get("error"),
|
Error: r.URL.Query().Get("error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
PetiteVue.createApp({
|
|
||||||
//$delimiters: ['${', '}'], // https://github.com/vuejs/petite-vue/pull/100
|
|
||||||
activeTab: defaultTab,
|
|
||||||
isActive(tab) {
|
|
||||||
return this.activeTab === tab
|
|
||||||
},
|
|
||||||
updateTab() {
|
|
||||||
this.activeTab = window.location.hash.slice(1) || defaultTab
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.updateTab()
|
|
||||||
window.addEventListener('hashchange', () => this.updateTab())
|
|
||||||
}
|
|
||||||
}).mount('#leaderboard-page')
|
|
@ -6,7 +6,6 @@
|
|||||||
<script>
|
<script>
|
||||||
const defaultTab = 'total'
|
const defaultTab = 'total'
|
||||||
</script>
|
</script>
|
||||||
<script type="module" src="assets/js/components/leaderboard.js"></script>
|
|
||||||
|
|
||||||
<body class="relative bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen {{ if .User }} max-w-screen-xl {{ else }} max-w-screen-lg {{end}} mx-auto justify-center">
|
<body class="relative bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen {{ if .User }} max-w-screen-xl {{ else }} max-w-screen-lg {{end}} mx-auto justify-center">
|
||||||
|
|
||||||
@ -19,34 +18,26 @@
|
|||||||
{{ template "login-btn.tpl.html" . }}
|
{{ template "login-btn.tpl.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<main class="mt-10 flex-grow flex justify-center w-full" v-scope @vue:mounted="mounted" id="leaderboard-page">
|
<main class="mt-10 flex-grow flex justify-center w-full" id="leaderboard-page">
|
||||||
<div class="flex flex-col flex-grow mt-10">
|
<div class="flex flex-col flex-grow mt-10">
|
||||||
<h1 class="font-semibold text-3xl text-white m-0 mb-4">Leaderboard</h1>
|
<h1 class="font-semibold text-3xl text-white m-0 mb-4">Leaderboard</h1>
|
||||||
|
|
||||||
<ul class="flex space-x-4 mb-16 text-gray-600">
|
<ul class="flex space-x-4 mb-16 text-gray-600">
|
||||||
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('total'), 'hover:text-gray-500': !isActive('total') }">
|
<li class="font-semibold text-2xl {{ if eq .By "" }} text-gray-300 {{ else }} hover:text-gray-500 {{ end }}">
|
||||||
<a href="leaderboard#total" @click="updateTab">Total</a>
|
<a href="leaderboard">Total</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('language'), 'hover:text-gray-500': !isActive('language') }">
|
<li class="font-semibold text-2xl {{ if eq .By "language" }} text-gray-300 {{ else }} hover:text-gray-500 {{ end }}">
|
||||||
<a href="leaderboard#language" @click="updateTab">By Language</a>
|
<a href="leaderboard?by=language">By Language</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div v-cloak id="total" class="tab flex flex-col space-y-4" v-if="isActive('total')">
|
<div id="total" class="tab flex flex-col space-y-4">
|
||||||
<ol>
|
<ol>
|
||||||
{{ range $i, $item := .Items }}
|
{{ range $i, $item := .Items }}
|
||||||
<li>{{ $item.Rank }} - {{ $item.UserID }} - {{ $item.Total | duration }}</li>
|
<li>{{ $item.Rank }} - {{ $item.UserID }} - {{ $item.Total | duration }}</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-cloak id="language" class="tab flex flex-col space-y-4" v-if="isActive('language')">
|
|
||||||
<ol>
|
|
||||||
{{ range $i, $item := .ItemsByLanguage }}
|
|
||||||
<li>{{ $item.Rank }} - {{ $item.UserID }} - {{ $item.Total | duration }}</li>
|
|
||||||
{{ end }}
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user