237 lines
6.8 KiB
Go
237 lines
6.8 KiB
Go
package controllers
|
|
|
|
import (
|
|
"lost-and-found/internal/models"
|
|
"lost-and-found/internal/services"
|
|
"lost-and-found/internal/utils"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type UserController struct {
|
|
userService *services.UserService
|
|
}
|
|
|
|
func NewUserController(db *gorm.DB) *UserController {
|
|
return &UserController{
|
|
userService: services.NewUserService(db),
|
|
}
|
|
}
|
|
|
|
// GetProfile gets user profile
|
|
// GET /api/user/profile
|
|
func (c *UserController) GetProfile(ctx *gin.Context) {
|
|
userObj, _ := ctx.Get("user")
|
|
user := userObj.(*models.User)
|
|
|
|
profile, err := c.userService.GetProfile(user.ID)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusNotFound, "Profile not found", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "Profile retrieved", profile.ToResponse())
|
|
}
|
|
|
|
// UpdateProfile updates user profile
|
|
// PUT /api/user/profile
|
|
func (c *UserController) UpdateProfile(ctx *gin.Context) {
|
|
userObj, _ := ctx.Get("user")
|
|
user := userObj.(*models.User)
|
|
|
|
var req services.UpdateProfileRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error())
|
|
return
|
|
}
|
|
|
|
ipAddress := ctx.ClientIP()
|
|
userAgent := ctx.Request.UserAgent()
|
|
|
|
updatedUser, err := c.userService.UpdateProfile(user.ID, req, ipAddress, userAgent)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Update failed", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "Profile updated", updatedUser.ToResponse())
|
|
}
|
|
|
|
// ChangePassword changes user password
|
|
// POST /api/user/change-password
|
|
func (c *UserController) ChangePassword(ctx *gin.Context) {
|
|
userObj, _ := ctx.Get("user")
|
|
user := userObj.(*models.User)
|
|
|
|
var req services.ChangePasswordRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error())
|
|
return
|
|
}
|
|
|
|
ipAddress := ctx.ClientIP()
|
|
userAgent := ctx.Request.UserAgent()
|
|
|
|
if err := c.userService.ChangePassword(user.ID, req, ipAddress, userAgent); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Password change failed", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "Password changed successfully", nil)
|
|
}
|
|
|
|
// GetStats gets user statistics
|
|
// GET /api/user/stats
|
|
func (c *UserController) GetStats(ctx *gin.Context) {
|
|
userObj, _ := ctx.Get("user")
|
|
user := userObj.(*models.User)
|
|
|
|
stats, err := c.userService.GetUserStats(user.ID)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get stats", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "Stats retrieved", stats)
|
|
}
|
|
|
|
// GetAllUsers gets all users (admin only)
|
|
// GET /api/admin/users
|
|
func (c *UserController) GetAllUsers(ctx *gin.Context) {
|
|
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
|
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))
|
|
|
|
users, total, err := c.userService.GetAllUsers(page, limit)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get users", err.Error())
|
|
return
|
|
}
|
|
|
|
var responses []models.UserResponse
|
|
for _, user := range users {
|
|
responses = append(responses, user.ToResponse())
|
|
}
|
|
|
|
utils.SendPaginatedResponse(ctx, http.StatusOK, "Users retrieved", responses, total, page, limit)
|
|
}
|
|
|
|
// GetUserByID gets user by ID (admin only)
|
|
// GET /api/admin/users/:id
|
|
func (c *UserController) GetUserByID(ctx *gin.Context) {
|
|
id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid user ID", err.Error())
|
|
return
|
|
}
|
|
|
|
user, err := c.userService.GetUserByID(uint(id))
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusNotFound, "User not found", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "User retrieved", user.ToResponse())
|
|
}
|
|
|
|
// UpdateUserRole updates user role (admin only)
|
|
// PATCH /api/admin/users/:id/role
|
|
func (c *UserController) UpdateUserRole(ctx *gin.Context) {
|
|
adminObj, _ := ctx.Get("user")
|
|
admin := adminObj.(*models.User)
|
|
|
|
userID, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid user ID", err.Error())
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
RoleID uint `json:"role_id" binding:"required"`
|
|
}
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error())
|
|
return
|
|
}
|
|
|
|
ipAddress := ctx.ClientIP()
|
|
userAgent := ctx.Request.UserAgent()
|
|
|
|
if err := c.userService.UpdateUserRole(admin.ID, uint(userID), req.RoleID, ipAddress, userAgent); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to update role", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "User role updated", nil)
|
|
}
|
|
|
|
// BlockUser blocks a user (admin only)
|
|
// POST /api/admin/users/:id/block
|
|
func (c *UserController) BlockUser(ctx *gin.Context) {
|
|
adminObj, _ := ctx.Get("user")
|
|
admin := adminObj.(*models.User)
|
|
|
|
userID, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid user ID", err.Error())
|
|
return
|
|
}
|
|
|
|
ipAddress := ctx.ClientIP()
|
|
userAgent := ctx.Request.UserAgent()
|
|
|
|
if err := c.userService.BlockUser(admin.ID, uint(userID), ipAddress, userAgent); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to block user", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "User blocked", nil)
|
|
}
|
|
|
|
// UnblockUser unblocks a user (admin only)
|
|
// POST /api/admin/users/:id/unblock
|
|
func (c *UserController) UnblockUser(ctx *gin.Context) {
|
|
adminObj, _ := ctx.Get("user")
|
|
admin := adminObj.(*models.User)
|
|
|
|
userID, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid user ID", err.Error())
|
|
return
|
|
}
|
|
|
|
ipAddress := ctx.ClientIP()
|
|
userAgent := ctx.Request.UserAgent()
|
|
|
|
if err := c.userService.UnblockUser(admin.ID, uint(userID), ipAddress, userAgent); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to unblock user", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "User unblocked", nil)
|
|
}
|
|
|
|
// DeleteUser deletes a user (admin only)
|
|
// DELETE /api/admin/users/:id
|
|
func (c *UserController) DeleteUser(ctx *gin.Context) {
|
|
adminObj, _ := ctx.Get("user")
|
|
admin := adminObj.(*models.User)
|
|
|
|
userID, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
|
|
if err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid user ID", err.Error())
|
|
return
|
|
}
|
|
|
|
ipAddress := ctx.ClientIP()
|
|
userAgent := ctx.Request.UserAgent()
|
|
|
|
if err := c.userService.DeleteUser(admin.ID, uint(userID), ipAddress, userAgent); err != nil {
|
|
utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to delete user", err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(ctx, http.StatusOK, "User deleted", nil)
|
|
} |