feat: add feature photo profile
This commit is contained in:
parent
a31a913658
commit
10ac83cf4e
|
@ -8,6 +8,7 @@ import (
|
|||
type UserResponseDTO struct {
|
||||
ID string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Avatar *string `json:"photoprofile,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
|
|
|
@ -77,3 +77,22 @@ func (h *UserProfileHandler) UpdateUserPassword(c *fiber.Ctx) error {
|
|||
|
||||
return utils.LogResponse(c, userResponse, "Password updated successfully")
|
||||
}
|
||||
|
||||
func (h *UserProfileHandler) UpdateUserAvatar(c *fiber.Ctx) error {
|
||||
userID, ok := c.Locals("userID").(string)
|
||||
if !ok || userID == "" {
|
||||
return utils.GenericErrorResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
||||
}
|
||||
|
||||
file, err := c.FormFile("avatar")
|
||||
if err != nil {
|
||||
return utils.GenericErrorResponse(c, fiber.StatusBadRequest, "No avatar file uploaded")
|
||||
}
|
||||
|
||||
userResponse, err := h.UserProfileService.UpdateUserAvatar(userID, file)
|
||||
if err != nil {
|
||||
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return utils.LogResponse(c, userResponse, "Avatar updated successfully")
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
type UserProfileRepository interface {
|
||||
FindByID(userID string) (*model.User, error)
|
||||
Update(user *model.User) error
|
||||
UpdateAvatar(userID, avatarURL string) error
|
||||
}
|
||||
|
||||
type userProfileRepository struct {
|
||||
|
@ -34,3 +35,12 @@ func (r *userProfileRepository) Update(user *model.User) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *userProfileRepository) UpdateAvatar(userID, avatarURL string) error {
|
||||
var user model.User
|
||||
err := r.DB.Model(&user).Where("id = ?", userID).Update("avatar", avatarURL).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -4,6 +4,9 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/pahmiudahgede/senggoldong/dto"
|
||||
|
@ -16,6 +19,7 @@ type UserProfileService interface {
|
|||
GetUserProfile(userID string) (*dto.UserResponseDTO, error)
|
||||
UpdateUserProfile(userID string, updateData dto.UpdateUserDTO) (*dto.UserResponseDTO, error)
|
||||
UpdateUserPassword(userID string, passwordData dto.UpdatePasswordDTO) (*dto.UserResponseDTO, error)
|
||||
UpdateUserAvatar(userID string, file *multipart.FileHeader) (*dto.UserResponseDTO, error)
|
||||
}
|
||||
|
||||
type userProfileService struct {
|
||||
|
@ -188,3 +192,69 @@ func (s *userProfileService) UpdateUserPassword(userID string, passwordData dto.
|
|||
|
||||
return userResponse, nil
|
||||
}
|
||||
|
||||
func (s *userProfileService) UpdateUserAvatar(userID string, file *multipart.FileHeader) (*dto.UserResponseDTO, error) {
|
||||
|
||||
avatarDir := "./public/uploads/avatars"
|
||||
if _, err := os.Stat(avatarDir); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(avatarDir, os.ModePerm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create avatar directory: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
extension := filepath.Ext(file.Filename)
|
||||
if extension != ".jpg" && extension != ".jpeg" && extension != ".png" {
|
||||
return nil, fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
|
||||
}
|
||||
|
||||
avatarFileName := fmt.Sprintf("%s_avatar%s", userID, extension)
|
||||
avatarPath := filepath.Join(avatarDir, avatarFileName)
|
||||
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open uploaded file: %v", err)
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
dst, err := os.Create(avatarPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create file: %v", err)
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
_, err = dst.ReadFrom(src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to save avatar file: %v", err)
|
||||
}
|
||||
|
||||
avatarURL := fmt.Sprintf("/uploads/avatars/%s", avatarFileName)
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -17,4 +17,5 @@ func UserProfileRouter(api fiber.Router) {
|
|||
api.Get("/user", middleware.AuthMiddleware, userProfileHandler.GetUserProfile)
|
||||
api.Put("/user/update-user", middleware.AuthMiddleware, userProfileHandler.UpdateUserProfile)
|
||||
api.Post("/user/update-user-password", middleware.AuthMiddleware, userProfileHandler.UpdateUserPassword)
|
||||
api.Put("/user/upload-photoprofile", middleware.AuthMiddleware, userProfileHandler.UpdateUserAvatar)
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
Loading…
Reference in New Issue