package admin import ( "net/http" "strconv" "gobeyhan/app/account/services" "gobeyhan/database/models" view "gobeyhan/views/admin/user" "github.com/gin-gonic/gin" ) type UserHandler struct { userService *services.UserService roleService *services.RoleService } func NewUserHandler() *UserHandler { return &UserHandler{ userService: services.NewUserService(), roleService: services.NewRoleService(), } } // List Users func (h *UserHandler) List(c *gin.Context) { users, _, err := h.userService.GetAllUsers(false, 1, 100) // TODO: Implement pagination if err != nil { c.String(http.StatusInternalServerError, "Error fetching users") return } view.List(users).Render(c.Request.Context(), c.Writer) } // New User Form func (h *UserHandler) New(c *gin.Context) { roles, _ := h.roleService.GetAllRoles() view.Create(roles, map[string]string{}).Render(c.Request.Context(), c.Writer) } // Create User Action func (h *UserHandler) Create(c *gin.Context) { username := c.PostForm("username") email := c.PostForm("email") password := c.PostForm("password") // Basic Validation errors := make(map[string]string) if username == "" { errors["username"] = "Username is required" } if email == "" { errors["email"] = "Email is required" } if password == "" { errors["password"] = "Password is required" } if len(errors) > 0 { roles, _ := h.roleService.GetAllRoles() view.Create(roles, errors).Render(c.Request.Context(), c.Writer) return } user := &models.User{ UserName: username, Email: email, } if err := h.userService.CreateUser(user, password); err != nil { errors["email"] = "Error creating user (e.g. email exists)" roles, _ := h.roleService.GetAllRoles() view.Create(roles, errors).Render(c.Request.Context(), c.Writer) return } // Handle Role Assignment roleIDStr := c.PostForm("role_id") if roleID, err := strconv.ParseUint(roleIDStr, 10, 64); err == nil && roleID > 0 { h.userService.AssignRole(user.ID, roleID) } else { // Assign default role if no role selected (or as fallback) h.userService.AssignDefaultRole(user.ID) } // Handle Email Verification emailVerified := c.PostForm("email_verified") == "on" if emailVerified { h.userService.UpdateUser(user.ID, map[string]interface{}{ "email_verified": true, }) } c.Redirect(http.StatusSeeOther, "/admin/users") } // Edit User Form func (h *UserHandler) Edit(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.String(http.StatusBadRequest, "Invalid ID") return } user, err := h.userService.GetUserByID(id) if err != nil || user == nil { c.String(http.StatusNotFound, "User not found") return } roles, _ := h.roleService.GetAllRoles() view.Edit(*user, roles, map[string]string{}).Render(c.Request.Context(), c.Writer) } // Update User Action func (h *UserHandler) Update(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.String(http.StatusBadRequest, "Invalid ID") return } username := c.PostForm("username") email := c.PostForm("email") password := c.PostForm("password") // Basic Validation errors := make(map[string]string) if username == "" { errors["username"] = "Username is required" } if email == "" { errors["email"] = "Email is required" } if len(errors) > 0 { user, _ := h.userService.GetUserByID(id) if user != nil { // Keep submitted values? simplified for now user.UserName = username user.Email = email roles, _ := h.roleService.GetAllRoles() view.Edit(*user, roles, errors).Render(c.Request.Context(), c.Writer) } return } updates := map[string]interface{}{ "username": username, "email": email, "email_verified": c.PostForm("email_verified") == "on", } if password != "" { updates["password"] = password } if err := h.userService.UpdateUser(id, updates); err != nil { c.String(http.StatusInternalServerError, "Error updating user") return } // Update Role roleIDStr := c.PostForm("role_id") if roleID, err := strconv.ParseUint(roleIDStr, 10, 64); err == nil && roleID > 0 { // Remove existing roles first (simplified approach for single role) // Ideally we should check if role changed user, _ := h.userService.GetUserByID(id) if len(user.Roles) > 0 { h.userService.RemoveRole(id, user.Roles[0].ID) } h.userService.AssignRole(id, roleID) } c.Redirect(http.StatusSeeOther, "/admin/users") } // Delete User Action func (h *UserHandler) Delete(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.String(http.StatusBadRequest, "Invalid ID") return } if err := h.userService.DeleteUser(id); err != nil { c.String(http.StatusInternalServerError, "Error deleting user") return } c.Redirect(http.StatusSeeOther, "/admin/users") }