package handlers import ( "net/http" "strconv" "game-admin/internal/config" "game-admin/internal/models" "github.com/gin-gonic/gin" "github.com/uptrace/bun" ) type UserHandler struct { db *bun.DB cfg *config.Config } func NewUserHandler(db *bun.DB, cfg *config.Config) *UserHandler { return &UserHandler{db: db, cfg: cfg} } func (h *UserHandler) List(c *gin.Context) { var users []models.User query := h.db.NewSelect().Model(&users).OrderExpr("id DESC") // Search if s := c.Query("search"); s != "" { like := "%" + s + "%" query = query.Where("username LIKE ? OR email LIKE ?", like, like) } // Role filter if r := c.Query("role"); r != "" { query = query.Where("role = ?", r) } err := query.Scan(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, users) } func (h *UserHandler) ListByGame(c *gin.Context) { gameID, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"}) return } var users []models.User query := h.db.NewSelect(). Model(&users). Join("JOIN user_games AS ug ON ug.user_id = u.id"). Where("ug.game_id = ?", gameID). OrderExpr("u.id DESC"). Distinct() if s := c.Query("search"); s != "" { if id, err := strconv.ParseInt(s, 10, 64); err == nil { query = query.Where("u.id = ?", id) } else { like := "%" + s + "%" query = query.Where("u.username LIKE ? OR u.email LIKE ?", like, like) } } err = query.Scan(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, users) } func (h *UserHandler) GetByID(c *gin.Context) { id, _ := strconv.ParseInt(c.Param("id"), 10, 64) user := new(models.User) err := h.db.NewSelect().Model(user). Relation("UserGames", func(q *bun.SelectQuery) *bun.SelectQuery { return q.Relation("Game") }). Where("u.id = ?", id). Scan(c) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) return } c.JSON(http.StatusOK, user) } func (h *UserHandler) UpdateRole(c *gin.Context) { id, _ := strconv.ParseInt(c.Param("id"), 10, 64) var req models.UpdateUserRoleRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } _, err := h.db.NewUpdate().Model((*models.User)(nil)). Set("role = ?", req.Role). Where("id = ?", id). Exec(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Role updated"}) } func (h *UserHandler) ToggleActive(c *gin.Context) { id, _ := strconv.ParseInt(c.Param("id"), 10, 64) _, err := h.db.NewUpdate().Model((*models.User)(nil)). Set("is_active = NOT is_active"). Where("id = ?", id). Exec(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Toggled"}) }