53 lines
1.2 KiB
Go
53 lines
1.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"database/sql"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/tas/horchposten/models"
|
|
)
|
|
|
|
// Leaderboard handles GET /api/analytics/leaderboard/
|
|
func Leaderboard(db *sql.DB) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
limit := 20
|
|
if l := c.QueryParam("limit"); l != "" {
|
|
parsed, err := strconv.Atoi(l)
|
|
if err == nil && parsed > 0 {
|
|
limit = parsed
|
|
}
|
|
}
|
|
if limit > 100 {
|
|
limit = 100
|
|
}
|
|
|
|
rows, err := db.Query(
|
|
`SELECT p.client_id, h.score, h.achieved_at
|
|
FROM high_scores h
|
|
JOIN players p ON p.id = h.player_id
|
|
ORDER BY h.score DESC
|
|
LIMIT ?`,
|
|
limit,
|
|
)
|
|
if err != nil {
|
|
return c.JSON(http.StatusInternalServerError, echo.Map{"error": "database error"})
|
|
}
|
|
defer rows.Close()
|
|
|
|
entries := make([]models.LeaderboardEntry, 0)
|
|
for rows.Next() {
|
|
var e models.LeaderboardEntry
|
|
var achievedAt string
|
|
if err := rows.Scan(&e.ClientID, &e.Score, &achievedAt); err != nil {
|
|
return c.JSON(http.StatusInternalServerError, echo.Map{"error": "scan error"})
|
|
}
|
|
e.AchievedAt = parseTime(achievedAt)
|
|
entries = append(entries, e)
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, echo.Map{"leaderboard": entries})
|
|
}
|
|
}
|