package handlers import ( "gobeyhan/app/account/services" "gobeyhan/database/models" "net/http" "strconv" "github.com/gin-gonic/gin" ) type UserHandler struct { service *services.UserService } func NewUserHandler(service *services.UserService) *UserHandler { return &UserHandler{service: service} } // AdminGetAllUsers godoc // @Summary Get all users (Admin) // @Description Get paginated list of all users // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param page query int false "Page number" default(1) // @Param limit query int false "Items per page" default(10) // @Param include_deleted query bool false "Include soft-deleted users" // @Success 200 {object} map[string]interface{} // @Router /api/v1/admin/users [get] func (h *UserHandler) AdminGetAllUsers(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10")) includeDeleted := c.DefaultQuery("include_deleted", "false") == "true" if page < 1 { page = 1 } if limit < 1 || limit > 100 { limit = 10 } users, total, err := h.service.GetAllUsers(includeDeleted, page, limit) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "data": users, "total": total, "page": page, "limit": limit, }) } // AdminGetUserByID godoc // @Summary Get user by ID (Admin) // @Description Get a single user by ID // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param id path int true "User ID" // @Success 200 {object} models.User // @Router /api/v1/admin/users/{id} [get] func (h *UserHandler) AdminGetUserByID(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } user, err := h.service.GetUserByID(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if user == nil { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) return } c.JSON(http.StatusOK, gin.H{"data": user}) } // AdminCreateUser godoc // @Summary Create a new user (Admin) // @Description Create a new user // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param user body models.User true "User object" // @Success 201 {object} models.User // @Router /api/v1/admin/users [post] func (h *UserHandler) AdminCreateUser(c *gin.Context) { var input struct { UserName string `json:"username"` Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required"` Avatar string `json:"avatar"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user := &models.User{ UserName: input.UserName, Email: input.Email, Avatar: input.Avatar, } if err := h.service.CreateUser(user, input.Password); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{"data": user}) } // AdminUpdateUser godoc // @Summary Update a user (Admin) // @Description Update an existing user // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param id path int true "User ID" // @Param user body models.User true "User object" // @Success 200 {object} models.User // @Router /api/v1/admin/users/{id} [put] func (h *UserHandler) AdminUpdateUser(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } var input map[string]interface{} if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.service.UpdateUser(id, input); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // Fetch updated user user, err := h.service.GetUserByID(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": user}) } // AdminDeleteUser godoc // @Summary Delete a user (Admin) // @Description Soft delete a user by ID // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param id path int true "User ID" // @Success 200 {object} map[string]string // @Router /api/v1/admin/users/{id} [delete] func (h *UserHandler) AdminDeleteUser(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } if err := h.service.DeleteUser(id); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"}) } // AdminRestoreUser godoc // @Summary Restore a deleted user (Admin) // @Description Restore a soft-deleted user // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param id path int true "User ID" // @Success 200 {object} map[string]string // @Router /api/v1/admin/users/{id}/restore [post] func (h *UserHandler) AdminRestoreUser(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } if err := h.service.RestoreUser(id); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "User restored successfully"}) } // AdminAssignRole godoc // @Summary Assign role to user (Admin) // @Description Assign a role to a user // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param id path int true "User ID" // @Param role_id body int true "Role ID" // @Success 200 {object} map[string]string // @Router /api/v1/admin/users/{id}/roles [post] func (h *UserHandler) AdminAssignRole(c *gin.Context) { idStr := c.Param("id") userID, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } var input struct { RoleID uint64 `json:"role_id" binding:"required"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.service.AssignRole(userID, input.RoleID); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Role assigned successfully"}) } // AdminRemoveRole godoc // @Summary Remove role from user (Admin) // @Description Remove a role from a user // @Tags admin,users // @Accept json // @Produce json // @Security BearerAuth // @Param id path int true "User ID" // @Param role_id path int true "Role ID" // @Success 200 {object} map[string]string // @Router /api/v1/admin/users/{id}/roles/{role_id} [delete] func (h *UserHandler) AdminRemoveRole(c *gin.Context) { userIDStr := c.Param("id") userID, err := strconv.ParseUint(userIDStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } roleIDStr := c.Param("role_id") roleID, err := strconv.ParseUint(roleIDStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid role ID"}) return } if err := h.service.RemoveRole(userID, roleID); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Role removed successfully"}) }