diff --git a/config/templates.go b/config/templates.go index 244d1d7..5eab0aa 100644 --- a/config/templates.go +++ b/config/templates.go @@ -9,4 +9,5 @@ const ( ResetPasswordTemplate = "reset-password.tpl.html" SettingsTemplate = "settings.tpl.html" SummaryTemplate = "summary.tpl.html" + LeaderboardTemplate = "leaderboard.tpl.html" ) diff --git a/main.go b/main.go index c289d36..28f0c53 100644 --- a/main.go +++ b/main.go @@ -212,6 +212,7 @@ func main() { // MVC Handlers summaryHandler := routes.NewSummaryHandler(summaryService, userService) settingsHandler := routes.NewSettingsHandler(userService, heartbeatService, summaryService, aliasService, aggregationService, languageMappingService, projectLabelService, keyValueService, mailService) + leaderboardHandler := routes.NewLeaderboardHandler(userService, leaderboardService) homeHandler := routes.NewHomeHandler(keyValueService) loginHandler := routes.NewLoginHandler(userService, mailService) imprintHandler := routes.NewImprintHandler(keyValueService) @@ -246,6 +247,7 @@ func main() { loginHandler.RegisterRoutes(rootRouter) imprintHandler.RegisterRoutes(rootRouter) summaryHandler.RegisterRoutes(rootRouter) + leaderboardHandler.RegisterRoutes(rootRouter) settingsHandler.RegisterRoutes(rootRouter) relayHandler.RegisterRoutes(rootRouter) diff --git a/models/view/leaderboard.go b/models/view/leaderboard.go new file mode 100644 index 0000000..ed8c03e --- /dev/null +++ b/models/view/leaderboard.go @@ -0,0 +1,22 @@ +package view + +import "github.com/muety/wakapi/models" + +type LeaderboardViewModel struct { + User *models.User + Items []*models.LeaderboardItem + ItemsByLanguage []*models.LeaderboardItem + ApiKey string + Success string + Error string +} + +func (s *LeaderboardViewModel) WithSuccess(m string) *LeaderboardViewModel { + s.Success = m + return s +} + +func (s *LeaderboardViewModel) WithError(m string) *LeaderboardViewModel { + s.Error = m + return s +} diff --git a/routes/leaderboard.go b/routes/leaderboard.go new file mode 100644 index 0000000..8905a86 --- /dev/null +++ b/routes/leaderboard.go @@ -0,0 +1,74 @@ +package routes + +import ( + "github.com/gorilla/mux" + conf "github.com/muety/wakapi/config" + "github.com/muety/wakapi/middlewares" + "github.com/muety/wakapi/models" + "github.com/muety/wakapi/models/view" + "github.com/muety/wakapi/services" + "net/http" +) + +type LeaderboardHandler struct { + config *conf.Config + userService services.IUserService + leaderboardService services.ILeaderboardService +} + +func NewLeaderboardHandler(userService services.IUserService, leaderboardService services.ILeaderboardService) *LeaderboardHandler { + return &LeaderboardHandler{ + config: conf.Get(), + userService: userService, + leaderboardService: leaderboardService, + } +} + +func (h *LeaderboardHandler) RegisterRoutes(router *mux.Router) { + r := router.PathPrefix("/leaderboard").Subrouter() + r.Use( + middlewares.NewAuthenticateMiddleware(h.userService). + WithRedirectTarget(defaultErrorRedirectTarget()). + WithOptionalFor([]string{"/"}). + Handler, + ) + r.Methods(http.MethodGet).HandlerFunc(h.GetIndex) +} + +func (h *LeaderboardHandler) GetIndex(w http.ResponseWriter, r *http.Request) { + if h.config.IsDev() { + loadTemplates() + } + templates[conf.LeaderboardTemplate].Execute(w, h.buildViewModel(r)) +} + +func (h *LeaderboardHandler) buildViewModel(r *http.Request) *view.LeaderboardViewModel { + user := middlewares.GetPrincipal(r) + + itemsGeneral, err := h.leaderboardService.GetByInterval(models.IntervalPast7Days) + if err != nil { + conf.Log().Request(r).Error("error while fetching general leaderboard items - %v", err) + return &view.LeaderboardViewModel{Error: criticalError} + } + + by := models.SummaryLanguage + itemsByLanguage, 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} + } + + var apiKey string + if user != nil { + apiKey = user.ApiKey + } + + return &view.LeaderboardViewModel{ + User: user, + Items: itemsGeneral, + ItemsByLanguage: itemsByLanguage, + ApiKey: apiKey, + Success: r.URL.Query().Get("success"), + Error: r.URL.Query().Get("error"), + } +} diff --git a/static/assets/js/components/leaderboard.js b/static/assets/js/components/leaderboard.js new file mode 100644 index 0000000..8b6288e --- /dev/null +++ b/static/assets/js/components/leaderboard.js @@ -0,0 +1,14 @@ +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') diff --git a/views/index.tpl.html b/views/index.tpl.html index 760b6f2..f03e0fe 100644 --- a/views/index.tpl.html +++ b/views/index.tpl.html @@ -9,12 +9,7 @@ {{ template "alerts.tpl.html" . }} -
-
- -  Login -
-
+{{ template "login-btn.tpl.html" . }}
diff --git a/views/leaderboard.tpl.html b/views/leaderboard.tpl.html new file mode 100644 index 0000000..3b6bd69 --- /dev/null +++ b/views/leaderboard.tpl.html @@ -0,0 +1,58 @@ + + + +{{ template "head.tpl.html" . }} + + + + + + +{{ template "alerts.tpl.html" . }} + +{{ if .User }} +{{ template "menu-main.tpl.html" . }} +{{ else }} +{{ template "header.tpl.html" . }} +{{ template "login-btn.tpl.html" . }} +{{ end }} + +
+
+

Leaderboard

+ + + +
+
    + {{ range $i, $item := .Items }} +
  1. {{ $item.Rank }} - {{ $item.UserID }} - {{ $item.Total | duration }}
  2. + {{ end }} +
+
+ +
+
    + {{ range $i, $item := .ItemsByLanguage }} +
  1. {{ $item.Rank }} - {{ $item.UserID }} - {{ $item.Total | duration }}
  2. + {{ end }} +
+
+
+
+ +{{ template "footer.tpl.html" . }} + +{{ template "foot.tpl.html" . }} + + + diff --git a/views/login-btn.tpl.html b/views/login-btn.tpl.html new file mode 100644 index 0000000..0781a56 --- /dev/null +++ b/views/login-btn.tpl.html @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/views/menu-main.tpl.html b/views/menu-main.tpl.html index fa41b0e..87e3cd9 100644 --- a/views/menu-main.tpl.html +++ b/views/menu-main.tpl.html @@ -10,6 +10,11 @@ + + + + + - -