Skip to content

Commit

Permalink
fix: 프로필 재수정 시, 이전 프로필 정보가 저장되어 있지 않음 (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
shinhyojeong committed Feb 1, 2024
2 parents af93684 + 30bcbb5 commit 7881021
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 71 deletions.
77 changes: 55 additions & 22 deletions src/components/shop/EditProfileModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -19,38 +22,71 @@ 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<EditProfileForm>(initialProfileForm)
const { uploaderRef, openUploader, changeImage } = useImageUploader({
onChange: async image => {
const uploadedImage = await onChangeImage(image)
setProfileForm({ ...profileForm, image: uploadedImage })
const [profileForm, setProfileForm] = useState<EditProfileForm>(profile)
const [nickNameValidate, setNickNameValidate] = useState(
initialNickNameValidate
)
const validateNickname = useValidateNickname()
const createUploadImage = useCreateUploadImagesMutation()

const handleChangeProfileImage = async (
image: EditProfileForm['image']
): Promise<void> => {
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: handleChangeProfileImage
})

const canEdit = nickNameValidate.isSuccess || profileForm.image.file

const handleChangeNickname: ChangeEventHandler<HTMLInputElement> = 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)
}

const handleClose = () => {
onClose?.()
setProfileForm(initialProfileForm)
setNickNameValidate(initialNickNameValidate)
}

useEffect(() => {
setProfileForm(profile)
}, [profile])

return (
<Modal isOpen={isOpen} onClose={handleClose}>
<Styled.Header>
Expand Down Expand Up @@ -83,7 +119,7 @@ export const EditProfileModal = ({
<Text color="grayScale70" styleType="body01M" tag="p">
닉네임
</Text>
<input
<Input
maxLength={NICK_NAME_MAX_LENGTH}
placeholder="닉네임을 입력해 주세요."
value={profileForm.nickname}
Expand All @@ -92,11 +128,11 @@ export const EditProfileModal = ({
<Text color="grayScale50" styleType="caption01M" tag="p">
{profileForm.nickname.length}/{NICK_NAME_MAX_LENGTH}
</Text>
{!!validate.message && (
{!!nickNameValidate.message && (
<Text
color={validate.isSuccess ? 'actSuccess' : 'actError'}
color={nickNameValidate.isSuccess ? 'actSuccess' : 'actError'}
styleType="caption01M">
{validate.message}
{nickNameValidate.message}
</Text>
)}
<Styled.DuplicateButton
Expand All @@ -108,10 +144,7 @@ export const EditProfileModal = ({
</Styled.EditNickName>
</Styled.Body>
<div>
<Button
disabled={!validate.isSuccess}
size="large"
onClick={handleConfirm}>
<Button disabled={!canEdit} size="large" onClick={handleConfirm}>
저장
</Button>
</div>
Expand Down
6 changes: 1 addition & 5 deletions src/components/shop/EditProfileModal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ export type EditProfileForm = {
export type EditProfileValidate = { isSuccess: boolean; message: string }

export type EditProfileModalProps = Pick<ModalProps, 'isOpen' | 'onClose'> & {
validate: EditProfileValidate
onValidateNickname(nickname: string): void
profile: EditProfileForm
onConfirm(profile: EditProfileForm): void
onChangeImage(
image: EditProfileForm['image']
): Promise<EditProfileForm['image']>
}
59 changes: 16 additions & 43 deletions src/components/shop/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 { useModal } from '@hooks'
import { useGetProfileQuery, useUpdateMyProfileMutation } from '@apis'
import { useAuth, useModal } from '@hooks'
import type { TradeActivityCodes } from '@types'
import { isNumber } from '@utils'

const initialEditProfileValidate = {
isSuccess: false,
message: ''
}

type ShopPageLayoutProps = {
memberId: number | null
currentTab: TradeActivityCodes
Expand All @@ -32,53 +22,32 @@ export const ShopPageLayout = ({
}: ShopPageLayoutProps) => {
const defaultTabIndex = tabList.findIndex(tab => tab === currentTab)
const [currentPage, setCurrentPage] = useState<TradeActivityCodes>(currentTab)
const [editProfileValidate, setEditProfileValidate] = useState(
initialEditProfileValidate
)
const { refetch: userRefetch } = useAuth()

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
})
// MEMO: 동일한 api를 다른 상태로 다루고 있어서 Header의 유저 정보 업데이트를 위해 두번 리패치해야하는 이슈가 있습니다.
// TODO: 추후에 Header와 동일한 유저 정보를 사용하도록 구조적인 변경이 필요합니다.
await profile.refetch()

handleCloseEditProfileModal()
await userRefetch()
}

return (
Expand Down Expand Up @@ -123,11 +92,15 @@ export const ShopPageLayout = ({
<Divider />
<EditProfileModal
isOpen={profileModal.isOpen}
validate={editProfileValidate}
onChangeImage={handleChangeProfileImage}
onClose={handleCloseEditProfileModal}
profile={{
nickname: profile.data.nickname,
image: {
id: String(profile.data.id),
url: profile.data.profileImageUrl
}
}}
onClose={profileModal.closeModal}
onConfirm={handleConfirmEditProfile}
onValidateNickname={handleValidateNickname}
/>
</div>
)
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const useAuth = () => {
isLogin,
isLoading: getMyProfileQuery.isLoading,
handleLogout,
user: getMyProfileQuery.data
user: getMyProfileQuery.data,
refetch: getMyProfileQuery.refetch
}
}

0 comments on commit 7881021

Please sign in to comment.