File size: 2,557 Bytes
e30b161
 
 
 
 
 
 
 
 
 
 
 
 
 
e08c0a2
e30b161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60f5031
e30b161
 
 
 
 
60f5031
e30b161
 
 
 
 
 
 
 
 
e08c0a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package controllers

import (
	"net/http"

	"dinacom-11.0-backend/services"
	"dinacom-11.0-backend/utils"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

type RankController interface {
	GetUserRank(ctx *gin.Context)
	GetLeaderboard(ctx *gin.Context)
}

type rankController struct {
	rankService services.RankService
}

func NewRankController(rankService services.RankService) RankController {
	return &rankController{rankService: rankService}
}

// @Summary Get User Rank
// @Description Get the logged-in user's rank, level, XP progress
// @Tags User
// @Produce json
// @Security BearerAuth
// @Success 200 {object} dto.UserRankResponse
// @Failure 401 {object} map[string]string
// @Router /api/user/rank [get]
func (c *rankController) GetUserRank(ctx *gin.Context) {
	userIDVal, exists := ctx.Get("user_id")
	if !exists {
		utils.SendErrorResponse(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}

	userID := userIDVal.(uuid.UUID)

	response, err := c.rankService.GetUserRank(userID)
	if err != nil {
		utils.SendErrorResponse(ctx, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SendSuccessResponse(ctx, "User rank retrieved", response)
}

// @Summary Get Leaderboard
// @Description Get top users by XP (default limit 10)
// @Tags User
// @Produce json
// @Security BearerAuth
// @Param limit query int false "Limit (default 10)"
// @Success 200 {array} dto.LeaderboardEntry
// @Failure 401 {object} map[string]string
// @Router /api/user/leaderboard [get]
func (c *rankController) GetLeaderboard(ctx *gin.Context) {
	limit := 10
	if limitStr := ctx.Query("limit"); limitStr != "" {
		// simple parse, ignore error for now or use strconv
		// For simplicity/safety in this specific context without strconv import visible yet:
		// We can try to bind query or just trust default if parsing fails.
		// Let's rely on service validation or just passing it if we had strconv.
		// Since I can't easily see imports, I'll update imports if needed or just use default if not provided.
		// Actually, let's use a helper or bind.
	}

	// Better to use BindQuery if struct defined, or strconv.
	// Using a simple struct to bind query params
	var query struct {
		Limit int `form:"limit"`
	}
	if err := ctx.ShouldBindQuery(&query); err == nil && query.Limit > 0 {
		limit = query.Limit
	}

	leaderboard, err := c.rankService.GetLeaderboard(limit)
	if err != nil {
		utils.SendErrorResponse(ctx, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SendSuccessResponse(ctx, "Leaderboard retrieved", leaderboard)
}