Skip to content

Commit

Permalink
Merge pull request #85 from team-nabi/NABI-256
Browse files Browse the repository at this point in the history
🎉 프로필, 닉네임 api 연결
  • Loading branch information
oaoong authored Nov 21, 2023
2 parents 1db9ab3 + 7fe6d3b commit 13bd6ea
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 64 deletions.
37 changes: 28 additions & 9 deletions src/app/(root)/(routes)/mypage/components/UserInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,52 @@
import React, { useState } from 'react'
import AvatarEditable from '@/components/domain/avatar-editable'
import TextEditable from '@/components/domain/text-editable'
import { useAuth } from '@/contexts/AuthProvider'
import { useToast } from '@/hooks/useToast'
import { postImageFile } from '@/services/images'
import { putUserNickname, putUserProfile } from '@/services/user/user'
import { User } from '@/types/user'

const UserInfo = () => {
const { currentUser } = useAuth()
type UserInfoProps = {
user: User
}

const UserInfo = ({ user }: UserInfoProps) => {
const { toast } = useToast()
const [isProfileChanged, setIsProfileChanged] = useState(true)
const [isNicknameChanged, setIsNicknameChanged] = useState(true)

const fileChangeHandler = async (file: File) => {
setIsProfileChanged(true)
try {
const _data = await putUserProfile({ file: file })
const resUpload = await postImageFile(file)
const resProfile = await putUserProfile(resUpload.data)
window.location.reload()
return resProfile.data
} catch (error) {
setIsProfileChanged(false)
console.log(error)
// TODO: toast error message 추가
toast({
title: '프로필 이미지 변경 실패',
description: '프로필 이미지 변경에 실패했습니다.',
variant: 'destructive',
})
}
}

const nicknameChangeHandler = async (nickname: string) => {
setIsNicknameChanged(true)
try {
const _data = await putUserNickname(nickname)
const res = await putUserNickname(nickname)
window.location.reload()
return res.data
} catch (error) {
setIsNicknameChanged(false)
console.log(error)
//TODO: toast error message 추가
toast({
title: '닉네임 변경 실패',
description: '닉네임 변경에 실패했습니다.',
variant: 'destructive',
})
}
}

Expand All @@ -39,12 +58,12 @@ const UserInfo = () => {
<AvatarEditable
fileChangeHandler={fileChangeHandler}
changedSuccessfully={isProfileChanged}
defaultImage={currentUser?.imageUrl}
defaultImage={user?.imageUrl}
/>
<TextEditable
onChangeHandler={nicknameChangeHandler}
changedSuccessfully={isNicknameChanged}
defaultText={currentUser?.nickname}
defaultText={user?.nickname}
/>
</div>
)
Expand Down
27 changes: 22 additions & 5 deletions src/app/(root)/(routes)/mypage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import React from 'react'
import PageTitle from '@/components/domain/page-title'
import ApiEndPoint from '@/config/apiEndPoint'
import apiClient from '@/services/apiClient'
import { User } from '@/types/user'
import { getServerCookie } from '@/utils/getServerCookie'
import UserInfo from './components/UserInfo'

const MyPage = () => {
const getUserInfo = async (): Promise<User> => {
const token = getServerCookie()
const res = await apiClient.get(
ApiEndPoint.getValidateUser(),
{},
{
Authorization: `${token}`,
},
)
return res.data.userInfo
}

const MyPage = async () => {
const userInfo = await getUserInfo()

return (
<main className="flex flex-col items-center gap-5 mt-5">
<header>
<h1>마이페이지</h1>
</header>
<PageTitle title="마이페이지" />
<section>
<UserInfo />
<UserInfo user={userInfo} />
</section>
<section>{/* TODO: 각 내용에 대한 라우팅 추가 */}</section>
</main>
Expand Down
10 changes: 3 additions & 7 deletions src/components/domain/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ import AppPath from '@/config/appPath'
import Assets from '@/config/assets'
import { useAuth } from '@/contexts/AuthProvider'
import Logo from '../logo'
import { MenuButton, Avatar } from './components/Avatar'

// type HeaderProps = {
// isLogin?: boolean
// }
import { MenuButton, AvatarWithDropdown } from './components'

const Header = () => {
const { isLoggedIn } = useAuth()
const { isLoggedIn, currentUser } = useAuth()
return (
<header className="absolute top-0 left-0 z-10 grid items-center justify-between w-full grid-cols-3 px-2 h-nav shadow-bottom bg-background-color">
<div className="flex items-center justify-start">
Expand All @@ -31,7 +27,7 @@ const Header = () => {
<Image src={Assets.alarmIcon} alt="alarm" />
</Button>
{/** TODO: 알림 컴포넌트로 변경 */}
<Avatar />
<AvatarWithDropdown imageUrl={currentUser?.imageUrl} />
{/** TODO: 아바타 컴포넌트로 변경 */}
</>
) : (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Cookies from 'js-cookie'
import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
import Button from '@/components/ui/button'
import {
DropdownMenu,
Expand All @@ -10,32 +10,13 @@ import {
DropdownMenuItem,
} from '@/components/ui/dropdown-menu'
import AppPath from '@/config/appPath'
import Assets from '@/config/assets'
import { Environment } from '@/config/environment'
import { DEFAULT_PROFILE_IMG } from '@/constants/image'
import apiClient from '@/services/apiClient'

//TODO: 공용 아바타 컴포넌트로 변경
const AvatarWithDropdown = ({ imageUrl }: { imageUrl?: string }) => {
const router = useRouter()

const MenuButton = () => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="dark:bg-white" size="icon" variant={null}>
<Image src={Assets.menuIcon} alt="menu" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>
<Link href={AppPath.home()}>홈으로</Link>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}

const Avatar = () => {
const onClickLogout = () => {
Cookies.remove(Environment.tokenName())
apiClient.setDefaultHeader('Authorization', '')
Expand All @@ -45,15 +26,27 @@ const Avatar = () => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant={'gradation'}>아바타</Button>
<Button variant={null}>
<Avatar size="md">
<AvatarImage imgUrl={imageUrl ?? DEFAULT_PROFILE_IMG} />
<AvatarFallback>profile</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem
onClick={() => {
router.push(AppPath.mypage())
}}
>
내 정보
</DropdownMenuItem>
<DropdownMenuItem onClick={onClickLogout}>로그아웃</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}

export { MenuButton, Avatar }
export default AvatarWithDropdown
33 changes: 33 additions & 0 deletions src/components/domain/header/components/MenuButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Image from 'next/image'
import Link from 'next/link'
import Button from '@/components/ui/button'
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
} from '@/components/ui/dropdown-menu'
import AppPath from '@/config/appPath'
import Assets from '@/config/assets'

const MenuButton = () => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="dark:bg-white" size="icon" variant={null}>
<Image src={Assets.menuIcon} alt="menu" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>
<Link href={AppPath.home()}>홈으로</Link>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}

export default MenuButton
4 changes: 4 additions & 0 deletions src/components/domain/header/components/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import AvatarWithDropdown from './AvatarWithDropdown'
import MenuButton from './MenuButton'

export { AvatarWithDropdown, MenuButton }
2 changes: 2 additions & 0 deletions src/components/domain/image-uploader/ImageUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ const ImageUploader = ({
isDeletable={isImageDeletable}
isThumbnail={isThumbnail}
onDeleteHandler={() => {
console.log(images)
setImages(images.filter((_, i) => i !== index))
onFilesChanged(images.filter((_, i) => i !== index))
}}
/>
)
Expand Down
1 change: 1 addition & 0 deletions src/components/domain/text-editable/TextEditable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const TextEditable = ({
const [value, setValue] = useState(defaultText)

useEffect(() => {
console.log('이름', defaultText)
if (!changedSuccessfully) {
setValue(() => defaultText)
}
Expand Down
10 changes: 6 additions & 4 deletions src/services/card/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ export type CardInfoRes = {
data: { cardInfo: CardDetail; userInfo: User }
}

const getCardInfo = async (cardId: number) => {
const response: CardInfoRes = await apiClient.get(
ApiEndPoint.getCardInfo(cardId),
)
const getCardInfo = async (
cardId: number,
): Promise<{ data: { cardInfo: CardDetail; userInfo: User } }> => {
const response = await apiClient.get(ApiEndPoint.getCardInfo(cardId), {
cache: 'no-store',
})
return response
}

Expand Down
28 changes: 16 additions & 12 deletions src/services/user/user.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import { revalidateTag } from 'next/cache'
import ApiEndPoint from '@/config/apiEndPoint'
import apiClient from '../apiClient'

type putUserProfileReq = {
file: File
}

const putUserProfile = async ({ file }: putUserProfileReq) => {
const formData = new FormData()
formData.append('profile', file)
const putUserProfile = async (imageUrl: string) => {
const response = await apiClient.put(
ApiEndPoint.putUserProfile(),
formData,
{
imageUrl,
},
{},
{
'Content-Type': 'multipart/form-data',
'Content-Type': 'application/json',
},
)

return response
}

const putUserNickname = async (nickname: string) => {
const response = await apiClient.put(ApiEndPoint.putUserNickname(), {
nickname,
})
const response = await apiClient.put(
ApiEndPoint.putUserNickname(),
{
nickname,
},
{},
{
'Content-Type': 'application/json',
},
)

return response
}
Expand Down
2 changes: 1 addition & 1 deletion src/types/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ interface User {
userId: number
accountId: string
nickname: string
role: 'USER' | 'ADMIN'
role: 'ROLE_USER' | 'ROLE_ADMIN'
createdDate: string
modifiedDate: string
imageUrl?: string
Expand Down

0 comments on commit 13bd6ea

Please sign in to comment.