refact: change code struct and fixing little state
This commit is contained in:
parent
d6cbd62f1b
commit
b741120918
|
@ -70,15 +70,15 @@ func (h *UserProfileHandler) UpdateUserPassword(c *fiber.Ctx) error {
|
||||||
return utils.ValidationErrorResponse(c, errors)
|
return utils.ValidationErrorResponse(c, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := h.UserProfileService.UpdateUserPassword(userID, passwordData)
|
message, err := h.UserProfileService.UpdateUserPassword(userID, passwordData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.GenericResponse(c, fiber.StatusBadRequest, err.Error())
|
return utils.GenericResponse(c, fiber.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.GenericResponse(c, fiber.StatusOK, "Password updated successfully")
|
return utils.GenericResponse(c, fiber.StatusOK, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UserProfileHandler) UpdateUserAvatar(c *fiber.Ctx) error {
|
func (h *UserProfileHandler) UpdateUserAvatar(c *fiber.Ctx) error {
|
||||||
|
|
||||||
userID, ok := c.Locals("userID").(string)
|
userID, ok := c.Locals("userID").(string)
|
||||||
if !ok || userID == "" {
|
if !ok || userID == "" {
|
||||||
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
||||||
|
@ -89,10 +89,10 @@ func (h *UserProfileHandler) UpdateUserAvatar(c *fiber.Ctx) error {
|
||||||
return utils.GenericResponse(c, fiber.StatusBadRequest, "No avatar file uploaded")
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "No avatar file uploaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
userResponse, err := h.UserProfileService.UpdateUserAvatar(userID, file)
|
message, err := h.UserProfileService.UpdateUserAvatar(userID, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.GenericResponse(c, fiber.StatusInternalServerError, err.Error())
|
return utils.GenericResponse(c, fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, userResponse, "Avatar updated successfully")
|
return utils.GenericResponse(c, fiber.StatusOK, message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ func (r *userProfileRepository) FindByID(userID string) (*model.User, error) {
|
||||||
var user model.User
|
var user model.User
|
||||||
err := r.DB.Preload("Role").Where("id = ?", userID).First(&user).Error
|
err := r.DB.Preload("Role").Where("id = ?", userID).First(&user).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, fmt.Errorf("user with ID %s not found", userID)
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,15 @@ import (
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const avatarDir = "./public/uploads/avatars"
|
||||||
|
|
||||||
|
var allowedExtensions = []string{".jpg", ".jpeg", ".png"}
|
||||||
|
|
||||||
type UserProfileService interface {
|
type UserProfileService interface {
|
||||||
GetUserProfile(userID string) (*dto.UserResponseDTO, error)
|
GetUserProfile(userID string) (*dto.UserResponseDTO, error)
|
||||||
UpdateUserProfile(userID string, updateData dto.UpdateUserDTO) (*dto.UserResponseDTO, error)
|
UpdateUserProfile(userID string, updateData dto.UpdateUserDTO) (*dto.UserResponseDTO, error)
|
||||||
UpdateUserPassword(userID string, passwordData dto.UpdatePasswordDTO) (string, error)
|
UpdateUserPassword(userID string, passwordData dto.UpdatePasswordDTO) (string, error)
|
||||||
UpdateUserAvatar(userID string, file *multipart.FileHeader) (*dto.UserResponseDTO, error)
|
UpdateUserAvatar(userID string, file *multipart.FileHeader) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type userProfileService struct {
|
type userProfileService struct {
|
||||||
|
@ -178,68 +182,81 @@ func (s *userProfileService) UpdateUserPassword(userID string, passwordData dto.
|
||||||
return "Password berhasil diupdate", nil
|
return "Password berhasil diupdate", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userProfileService) UpdateUserAvatar(userID string, file *multipart.FileHeader) (*dto.UserResponseDTO, error) {
|
func (s *userProfileService) UpdateUserAvatar(userID string, file *multipart.FileHeader) (string, error) {
|
||||||
|
|
||||||
avatarDir := "./public/uploads/avatars"
|
if err := ensureAvatarDirectoryExists(); err != nil {
|
||||||
if _, err := os.Stat(avatarDir); os.IsNotExist(err) {
|
return "", err
|
||||||
err := os.MkdirAll(avatarDir, os.ModePerm)
|
}
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create avatar directory: %v", err)
|
if err := validateAvatarFile(file); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedUser, err := s.UserProfileRepo.FindByID(userID)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to retrieve user data: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if updatedUser.Avatar != nil && *updatedUser.Avatar != "" {
|
||||||
|
oldAvatarPath := "./public" + *updatedUser.Avatar
|
||||||
|
if err := os.Remove(oldAvatarPath); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to remove old avatar: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension := filepath.Ext(file.Filename)
|
avatarURL, err := saveAvatarFile(file, userID)
|
||||||
if extension != ".jpg" && extension != ".jpeg" && extension != ".png" {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = s.UserProfileRepo.UpdateAvatar(userID, avatarURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to update avatar in the database: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Foto profil berhasil diupdate", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureAvatarDirectoryExists() error {
|
||||||
|
if _, err := os.Stat(avatarDir); os.IsNotExist(err) {
|
||||||
|
if err := os.MkdirAll(avatarDir, os.ModePerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to create avatar directory: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateAvatarFile(file *multipart.FileHeader) error {
|
||||||
|
extension := filepath.Ext(file.Filename)
|
||||||
|
for _, ext := range allowedExtensions {
|
||||||
|
if extension == ext {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveAvatarFile(file *multipart.FileHeader, userID string) (string, error) {
|
||||||
|
extension := filepath.Ext(file.Filename)
|
||||||
avatarFileName := fmt.Sprintf("%s_avatar%s", userID, extension)
|
avatarFileName := fmt.Sprintf("%s_avatar%s", userID, extension)
|
||||||
avatarPath := filepath.Join(avatarDir, avatarFileName)
|
avatarPath := filepath.Join(avatarDir, avatarFileName)
|
||||||
|
|
||||||
src, err := file.Open()
|
src, err := file.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open uploaded file: %v", err)
|
return "", fmt.Errorf("failed to open uploaded file: %v", err)
|
||||||
}
|
}
|
||||||
defer src.Close()
|
defer src.Close()
|
||||||
|
|
||||||
dst, err := os.Create(avatarPath)
|
dst, err := os.Create(avatarPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create file: %v", err)
|
return "", fmt.Errorf("failed to create file: %v", err)
|
||||||
}
|
}
|
||||||
defer dst.Close()
|
defer dst.Close()
|
||||||
|
|
||||||
_, err = dst.ReadFrom(src)
|
_, err = dst.ReadFrom(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to save avatar file: %v", err)
|
return "", fmt.Errorf("failed to save avatar file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
avatarURL := fmt.Sprintf("/uploads/avatars/%s", avatarFileName)
|
return fmt.Sprintf("/uploads/avatars/%s", avatarFileName), nil
|
||||||
|
|
||||||
err = s.UserProfileRepo.UpdateAvatar(userID, avatarURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to update avatar in the database: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
updatedUser, err := s.UserProfileRepo.FindByID(userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to retrieve updated user data: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
createdAt, _ := utils.FormatDateToIndonesianFormat(updatedUser.CreatedAt)
|
|
||||||
updatedAt, _ := utils.FormatDateToIndonesianFormat(updatedUser.UpdatedAt)
|
|
||||||
|
|
||||||
userResponse := &dto.UserResponseDTO{
|
|
||||||
ID: updatedUser.ID,
|
|
||||||
Username: updatedUser.Username,
|
|
||||||
Avatar: updatedUser.Avatar,
|
|
||||||
Name: updatedUser.Name,
|
|
||||||
Phone: updatedUser.Phone,
|
|
||||||
Email: updatedUser.Email,
|
|
||||||
EmailVerified: updatedUser.EmailVerified,
|
|
||||||
RoleName: updatedUser.Role.RoleName,
|
|
||||||
CreatedAt: createdAt,
|
|
||||||
UpdatedAt: updatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
return userResponse, nil
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue