Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] - 프로필 이미지 수정 기능 및 여행기 등록 시 여행 장소마다 국가 코드 주도록 구현 #535

Merged
merged 24 commits into from
Oct 21, 2024
Merged
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
004644c
refactor(Drawer): 기존 헤드와 높이 달라 선 위치가 다른 문제 개선
simorimi Oct 10, 2024
cef7429
feat: 장소 필터링을 위하여 장소 등록시 countryCode를 보내도록 기능 구현
simorimi Oct 13, 2024
7912136
refactor(AvatarCircle): props $네이밍 수정
simorimi Oct 14, 2024
0aa2cfc
Merge branch 'develop/fe' of https://github.com/woowacourse-teams/202…
simorimi Oct 14, 2024
dde854e
refactor(MyTravelogue):$ 제거에 따른 수정
simorimi Oct 15, 2024
932e318
refactor(usePostUploadImages): resize 와 convert 처리 내부에서 하도록 수정
simorimi Oct 15, 2024
aa16247
refactor(MainPage): div semantic 태그인 button으로 수정
simorimi Oct 15, 2024
2eb4464
feat(ProfileImageEditModalBottomSheet): 기능 구현
simorimi Oct 15, 2024
537c3e8
feat(usePutProfile): api 명세 변경에 따라 patch를 put으로, imageUrl body 값에 부여
simorimi Oct 15, 2024
98076f6
refactor(AvatarCircle): props 유연하게 수정
simorimi Oct 16, 2024
fbc78f4
feat(useMyPage): 훅 구현
simorimi Oct 16, 2024
9321263
feat(MyPage): 프로필 이미지 수정 기능 구현
simorimi Oct 16, 2024
3f702c4
refactor(MyPage): 기능 단위로 pr 분리하기 위한 수정
simorimi Oct 16, 2024
ae9be47
refactor(SearchPage): 기능 단위로 pr 분리하기 위한 수정
simorimi Oct 16, 2024
01b6786
refactor(useMyPage): useToggle 사용하도록 수정
simorimi Oct 16, 2024
c7561fd
refactor(common): 반복되는 타입PlaceInfo 타입으로 선언 및 수정
simorimi Oct 20, 2024
b889315
refactor(constants): 상수들 파일로 분리
simorimi Oct 20, 2024
cac5077
refactor(useMyPage): 책임에 따라 각각 커스텀 훅으로 분리
simorimi Oct 20, 2024
7e6ca5e
refactor(constants): 상수 파일로 분리
simorimi Oct 20, 2024
f318d32
refactor(usePostUploadImages): max width, height 값 받을 수 있도록 수정
simorimi Oct 20, 2024
c810327
refactor(usePostUploadImages): max width, height 값 받을 수 있도록 수정
simorimi Oct 20, 2024
0ec73d3
Merge branch 'feature/fe/#519' of https://github.com/woowacourse-team…
simorimi Oct 20, 2024
3f18f98
refactor(useProfileInitialization): 의존성 배열 추가
simorimi Oct 21, 2024
211c7d6
refactor: useCallback으로 update 함수 감싸주도록 수정
simorimi Oct 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions frontend/src/components/pages/my/hooks/useMyPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React, { useEffect, useRef, useState } from "react";

import { usePostUploadImages } from "@queries/usePostUploadImages";
import usePutProfile from "@queries/usePutProfile";
import { useUserProfile } from "@queries/useUserProfile";

import { FORM_VALIDATIONS_MAP } from "@constants/formValidation";

const useMyPage = () => {
const { data, status, error } = useUserProfile();

const onError = (error: Error) => {
alert(error.message);
setNickname(data?.nickname ?? "");
};

const { mutate: mutateModifyProfile } = usePutProfile(onError);

const profileImageFileInputRef = useRef<HTMLInputElement>(null);

const [profileImageUrl, setProfileImageUrl] = useState(data?.profileImageUrl ?? "");
const [nickname, setNickname] = useState(data?.nickname ?? "");

const [isModifying, setIsModifying] = useState(false);
const [isProfileImageLoading, setIsProfileImageLoading] = useState(false);

const [isModalOpen, setIsModalOpen] = useState(false);

const handleClickEditModalOpenButton = () => setIsModalOpen(true);
const handleClickEditModalCloseButton = () => setIsModalOpen(false);

const handleClickProfileEditButton = () => setIsModifying(true);
const handleClickProfileImageEditButton = () => profileImageFileInputRef.current?.click();

const { mutateAsync: mutateAddImage } = usePostUploadImages();

const handleChangeProfileImage = async (e: React.ChangeEvent<HTMLInputElement>) => {
setIsProfileImageLoading(true);
setIsModalOpen(false);

const files = Array.from(e.target.files as FileList);
const profileImage = await mutateAddImage(files);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용자 프로필은 여행기 썸네일, 여행기 장소와 달리 크기가 작지만,
usePostUploadImages에서 똑같이 max width가 900대로 resize될텐데요
usePostUploadImages에서 max width, max height를 props로 받게해서 사용자 이미지는 레티나 디스플레이 대응해서 아바타 프로필 컴포넌트 최대 widht의 2배로 값 넣어주면 더 좋은 최적화가 될 것 같습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 부분 위와 마찬가지로 수정했습니다 고마워요 :)


setProfileImageUrl(profileImage[0]);
};

const handleLoadProfileImage = () => {
setIsProfileImageLoading(false);
};

const handleClickProfileImageDeleteButton = () => {
setProfileImageUrl("");

setIsModalOpen(false);
};

const handleClickProfileEditConfirmButton = () => {
const trimmedNickname = nickname.trim();
const newNickname = trimmedNickname || data?.nickname || "";

setNickname(newNickname);
mutateModifyProfile({ nickname: newNickname, profileImageUrl: profileImageUrl });

setIsModifying(false);
};

const handleClickProfileEditCancelButton = () => {
setNickname(data?.nickname ?? "");
setProfileImageUrl(data?.profileImageUrl ?? "");

setIsModifying(false);
};

const handleChangeNickname = (e: React.ChangeEvent<HTMLInputElement>) => {
setNickname(
e.target.value.slice(
FORM_VALIDATIONS_MAP.title.minLength,
FORM_VALIDATIONS_MAP.title.maxLength,
),
);
};

useEffect(() => {
if (data?.nickname) setNickname(data.nickname);
if (data?.profileImageUrl) setProfileImageUrl(data.profileImageUrl);
}, [data?.nickname, data?.profileImageUrl]);

return {
states: { profileImageUrl, nickname, isModifying, isProfileImageLoading, isModalOpen },
handlers: {
handleClickEditModalOpenButton,
handleClickEditModalCloseButton,
handleClickProfileEditButton,
handleClickProfileImageEditButton,
handleChangeProfileImage,
handleLoadProfileImage,
handleClickProfileImageDeleteButton,
handleClickProfileEditConfirmButton,
handleClickProfileEditCancelButton,
handleChangeNickname,
},
userProfile: { data, status, error },
profileImageFileInputRef,
};
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시간이 충분하다면 이 훅을 조금 더 리팩터링 해보는 것도 좋을거 같단 생각이 들었어요,,, (너무 많은 책임들이 쏠려 있어서 그런지 코드 해석에 시간이 걸렸어요)

제 생각에는

  1. 프로필을 초기화 하는 책임(useEffect)
  2. 프로필 수정 모달에 대한 책임(handleClickEditModalCloseButton, handleClickProfileImageEditButton, handleClickProfileImageDeleteButton, handleClickEditModalOpenButton)
  3. 프로필 수정에 대한 책임(handleClickProfileEditButton, handleChangeProfileImage, handleLoadProfileImage, handleClickProfileEditConfirmButton, handleClickProfileEditCancelButton, handleChangeNickname)

정도로만 나눠도 괜찮을거 같다는 생각이 들었어요~!

Copy link
Author

@simorimi simorimi Oct 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우선 states, handler 이런식으로 반환하던 것을 editModal, profileImage, profileNickname, ProfileEdit, userProfile 로 반환하고 해당 순서로 정리해 뒀습니다. 또한 해당 부분을 각각 훅으로 분리해서 훨씬 가독성이 좋아졌네요 좋은 피드백 감사합니다 :)


export default useMyPage;