From e4ba0c153986dfeaaa98d60fc3e6a5a9fa719e16 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 1 Feb 2024 00:54:18 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=20=EC=98=A4=ED=94=88=EC=8B=9C=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9E=85=EB=A0=A5=EB=90=98?= =?UTF-8?q?=EC=96=B4=20=EC=9E=88=EB=8F=84=EB=A1=9D,=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=88=98=EC=A0=95=20=EB=AA=A8=EB=8B=AC=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/EditProfileModal/index.tsx | 77 +++++++++++++------ src/components/shop/EditProfileModal/types.ts | 6 +- src/components/shop/layout/index.tsx | 53 +++---------- 3 files changed, 67 insertions(+), 69 deletions(-) diff --git a/src/components/shop/EditProfileModal/index.tsx b/src/components/shop/EditProfileModal/index.tsx index da764a73..b19d7483 100644 --- a/src/components/shop/EditProfileModal/index.tsx +++ b/src/components/shop/EditProfileModal/index.tsx @@ -5,12 +5,15 @@ import { Button, Text, Icon, - useImageUploader + useImageUploader, + Input } from '@offer-ui/react' import type { ChangeEventHandler, ReactElement } from 'react' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { Styled } from './styled' import type { EditProfileForm, EditProfileModalProps } from './types' +import { useValidateNickname } from '@hooks/useValidateNickname' +import { useCreateUploadImagesMutation } from '@apis' const NICK_NAME_MAX_LENGTH = 20 @@ -19,29 +22,57 @@ const initialProfileForm = { nickname: '' } +const initialNickNameValidate = { + isSuccess: false, + message: '' +} + export const EditProfileModal = ({ isOpen, - validate, - onValidateNickname, + profile, onClose, - onConfirm, - onChangeImage + onConfirm }: EditProfileModalProps): ReactElement => { - const [profileForm, setProfileForm] = - useState(initialProfileForm) - const { uploaderRef, openUploader, changeImage } = useImageUploader({ - onChange: async image => { - const uploadedImage = await onChangeImage(image) - setProfileForm({ ...profileForm, image: uploadedImage }) + const validateNickname = useValidateNickname() + + const [profileForm, setProfileForm] = useState(profile) + const [nickNameValidate, setNickNameValidate] = useState( + initialNickNameValidate + ) + const createUploadImage = useCreateUploadImagesMutation() + const canEdit = nickNameValidate.isSuccess || profileForm.image.file + + const handleChangeProfileImage = async ( + image: EditProfileForm['image'] + ): Promise => { + if (!image.file) { + return } + + const imageFormData = new FormData() + imageFormData.append('files', image.file) + const { imageUrls } = await createUploadImage.mutateAsync(imageFormData) + + setProfileForm(prev => ({ + ...prev, + image: { id: image.id, file: image.file, url: imageUrls[0] } + })) + } + + const { uploaderRef, openUploader, changeImage } = useImageUploader({ + onChange: async image => handleChangeProfileImage(image) }) const handleChangeNickname: ChangeEventHandler = e => { setProfileForm({ ...profileForm, nickname: e.target.value }) } - const handleClickDuplicateButton = () => { - onValidateNickname(profileForm.nickname.trim()) + + const handleClickDuplicateButton = async () => { + const validate = await validateNickname(profileForm.nickname.trim()) + + setNickNameValidate(validate) } + const handleConfirm = () => { onConfirm(profileForm) } @@ -49,8 +80,13 @@ export const EditProfileModal = ({ const handleClose = () => { onClose?.() setProfileForm(initialProfileForm) + setNickNameValidate(initialNickNameValidate) } + useEffect(() => { + setProfileForm(profile) + }, [profile]) + return ( @@ -83,7 +119,7 @@ export const EditProfileModal = ({ 닉네임 - {profileForm.nickname.length}/{NICK_NAME_MAX_LENGTH} - {!!validate.message && ( + {!!nickNameValidate.message && ( - {validate.message} + {nickNameValidate.message} )}
-
diff --git a/src/components/shop/EditProfileModal/types.ts b/src/components/shop/EditProfileModal/types.ts index 99ec214b..46fbf2fd 100644 --- a/src/components/shop/EditProfileModal/types.ts +++ b/src/components/shop/EditProfileModal/types.ts @@ -8,10 +8,6 @@ export type EditProfileForm = { export type EditProfileValidate = { isSuccess: boolean; message: string } export type EditProfileModalProps = Pick & { - validate: EditProfileValidate - onValidateNickname(nickname: string): void + profile: EditProfileForm onConfirm(profile: EditProfileForm): void - onChangeImage( - image: EditProfileForm['image'] - ): Promise } diff --git a/src/components/shop/layout/index.tsx b/src/components/shop/layout/index.tsx index ae775441..b17c3584 100644 --- a/src/components/shop/layout/index.tsx +++ b/src/components/shop/layout/index.tsx @@ -7,21 +7,11 @@ import type { EditProfileForm } from '../EditProfileModal/types' import { ProfileBox } from '../ProfileBox' import { Tabs } from '@components/common' import { pageTabs, tabList } from '@components/shop/pageTabs' -import { useValidateNickname } from '@hooks/useValidateNickname' -import { - useCreateUploadImagesMutation, - useGetProfileQuery, - useUpdateMyProfileMutation -} from '@apis' +import { useGetProfileQuery, useUpdateMyProfileMutation } from '@apis' import { useModal } from '@hooks' import type { TradeActivityCodes } from '@types' import { isNumber } from '@utils' -const initialEditProfileValidate = { - isSuccess: false, - message: '' -} - type ShopPageLayoutProps = { memberId: number | null currentTab: TradeActivityCodes @@ -32,53 +22,28 @@ export const ShopPageLayout = ({ }: ShopPageLayoutProps) => { const defaultTabIndex = tabList.findIndex(tab => tab === currentTab) const [currentPage, setCurrentPage] = useState(currentTab) - const [editProfileValidate, setEditProfileValidate] = useState( - initialEditProfileValidate - ) const profile = useGetProfileQuery(memberId) - const createUploadImage = useCreateUploadImagesMutation() const updateMyProfile = useUpdateMyProfileMutation() const isLogin = !isNumber(memberId) const profileModal = useModal() const router = useRouter() - const validateNickname = useValidateNickname() const handleChangePage = (code: TradeActivityCodes) => (): void => { router.push(`${router.pathname}?tab=${code}`) setCurrentPage(code) } - const handleValidateNickname = async (nickname: string) => { - const validate = await validateNickname(nickname) - setEditProfileValidate(validate) - } - const handleChangeProfileImage = async (image: EditProfileForm['image']) => { - if (!image.file) { - return image - } - - const imageFormData = new FormData() - imageFormData.append('files', image.file) - const { imageUrls } = await createUploadImage.mutateAsync(imageFormData) - - return { id: image.id, file: image.file, url: imageUrls[0] } - } - - const handleCloseEditProfileModal = () => { - setEditProfileValidate(initialEditProfileValidate) - profileModal.closeModal() - } const handleConfirmEditProfile = async (profileForm: EditProfileForm) => { + profileModal.closeModal() + await updateMyProfile.mutateAsync({ memberId: profile.data.id, nickname: profileForm.nickname, profileImageUrl: profileForm.image.url }) await profile.refetch() - - handleCloseEditProfileModal() } return ( @@ -123,11 +88,15 @@ export const ShopPageLayout = ({ ) From e01a78636cb026e645278a65b3f34a246149f022 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 1 Feb 2024 01:01:00 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=8B=9C=20Header=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=8F=84=20=EB=B3=80=EA=B2=BD=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/shop/layout/index.tsx | 6 +++++- src/hooks/useAuth.ts | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/shop/layout/index.tsx b/src/components/shop/layout/index.tsx index b17c3584..650d89f0 100644 --- a/src/components/shop/layout/index.tsx +++ b/src/components/shop/layout/index.tsx @@ -8,7 +8,7 @@ import { ProfileBox } from '../ProfileBox' import { Tabs } from '@components/common' import { pageTabs, tabList } from '@components/shop/pageTabs' import { useGetProfileQuery, useUpdateMyProfileMutation } from '@apis' -import { useModal } from '@hooks' +import { useAuth, useModal } from '@hooks' import type { TradeActivityCodes } from '@types' import { isNumber } from '@utils' @@ -22,6 +22,7 @@ export const ShopPageLayout = ({ }: ShopPageLayoutProps) => { const defaultTabIndex = tabList.findIndex(tab => tab === currentTab) const [currentPage, setCurrentPage] = useState(currentTab) + const { refetch: userRefetch } = useAuth() const profile = useGetProfileQuery(memberId) const updateMyProfile = useUpdateMyProfileMutation() @@ -43,7 +44,10 @@ export const ShopPageLayout = ({ nickname: profileForm.nickname, profileImageUrl: profileForm.image.url }) + // MEMO: 동일한 api를 다른 상태로 다루고 있어서 Header의 유저 정보 업데이트를 위해 두번 리패치해야하는 이슈가 있습니다. + // TODO: 추후에 Header와 동일한 유저 정보를 사용하도록 구조적인 변경이 필요합니다. await profile.refetch() + await userRefetch() } return ( diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts index edf04ece..9dd8e0e3 100644 --- a/src/hooks/useAuth.ts +++ b/src/hooks/useAuth.ts @@ -25,6 +25,7 @@ export const useAuth = () => { isLogin, isLoading: getMyProfileQuery.isLoading, handleLogout, - user: getMyProfileQuery.data + user: getMyProfileQuery.data, + refetch: getMyProfileQuery.refetch } } From 30bcbb5ba9e089d94f27a34cfe7274735ce02528 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 1 Feb 2024 01:03:49 +0900 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=AA=A8=EB=8B=AC=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/shop/EditProfileModal/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/shop/EditProfileModal/index.tsx b/src/components/shop/EditProfileModal/index.tsx index b19d7483..6a0b2410 100644 --- a/src/components/shop/EditProfileModal/index.tsx +++ b/src/components/shop/EditProfileModal/index.tsx @@ -33,14 +33,12 @@ export const EditProfileModal = ({ onClose, onConfirm }: EditProfileModalProps): ReactElement => { - const validateNickname = useValidateNickname() - const [profileForm, setProfileForm] = useState(profile) const [nickNameValidate, setNickNameValidate] = useState( initialNickNameValidate ) + const validateNickname = useValidateNickname() const createUploadImage = useCreateUploadImagesMutation() - const canEdit = nickNameValidate.isSuccess || profileForm.image.file const handleChangeProfileImage = async ( image: EditProfileForm['image'] @@ -60,9 +58,11 @@ export const EditProfileModal = ({ } const { uploaderRef, openUploader, changeImage } = useImageUploader({ - onChange: async image => handleChangeProfileImage(image) + onChange: handleChangeProfileImage }) + const canEdit = nickNameValidate.isSuccess || profileForm.image.file + const handleChangeNickname: ChangeEventHandler = e => { setProfileForm({ ...profileForm, nickname: e.target.value }) }