-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8473476
commit ab50d05
Showing
15 changed files
with
282 additions
and
125 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
'use client' | ||
|
||
import Image from 'next/image' | ||
import Link from 'next/link' | ||
import { useRouter } from 'next/navigation' | ||
|
||
import { useEffect, useState } from 'react' | ||
|
||
import { useForm, type SubmitHandler } from 'react-hook-form' | ||
|
||
import { ROUTE } from '@/app/_constants/route' | ||
import { type Champion } from '@/app/_service/auth/auth.types' | ||
import { getKakaoAccessToken, removeKakaoAccessToken, setAccessToken } from '@/app/_utils/token' | ||
|
||
import { useLoginQuery, useSignUpMutation } from './queries' | ||
|
||
const PROFILES = { | ||
DEFAULT: { | ||
RED: '/images/profile-red-1.png', | ||
YELLOW: '/images/profile-yellow-1.png', | ||
GREEN: '/images/profile-green-1.png', | ||
BLUE: '/images/profile-blue-1.png', | ||
BEIGE: '/images/profile-beige-1.png', | ||
PINK: '/images/profile-pink-1.png', | ||
}, | ||
SELECTED: { | ||
RED: '/images/profile-red-1-selected.png', | ||
YELLOW: '/images/profile-yellow-1-selected.png', | ||
GREEN: '/images/profile-green-1-selected.png', | ||
BLUE: '/images/profile-blue-1-selected.png', | ||
BEIGE: '/images/profile-beige-1-selected.png', | ||
PINK: '/images/profile-pink-1-selected.png', | ||
}, | ||
} | ||
|
||
interface Inputs { | ||
nickname: string | ||
} | ||
|
||
export default function Register() { | ||
const router = useRouter() | ||
|
||
const [selectedChampion, setSelectedChampion] = useState<Champion>('RED') | ||
|
||
const { register, handleSubmit, watch } = useForm<Inputs>({ | ||
mode: 'onChange', | ||
defaultValues: { | ||
nickname: '', | ||
}, | ||
}) | ||
|
||
const loginQuery = useLoginQuery({ accessToken: getKakaoAccessToken() }) | ||
const signUpMutation = useSignUpMutation() | ||
|
||
const onSubmit: SubmitHandler<Inputs> = (data) => { | ||
signUpMutation.mutate( | ||
{ | ||
accessToken: getKakaoAccessToken(), | ||
nickname: data.nickname, | ||
champion: selectedChampion, | ||
}, | ||
{ | ||
onSuccess: async () => { | ||
const { data } = await loginQuery.refetch() | ||
|
||
removeKakaoAccessToken() | ||
setAccessToken(data?.data.token) | ||
|
||
router.push(ROUTE.HOME) | ||
}, | ||
} | ||
) | ||
} | ||
const errorMessage = loginQuery.error?.response?.data.message | ||
const invalidKakaoToken = errorMessage === '카카오 access 토큰이 유효하지 않습니다.' | ||
const isNeedToRegister = | ||
errorMessage === 'provider_id가 DB에 없어 회원가입 필요, JWT토큰 생성 불가. 요청에 실패했습니다.' | ||
|
||
useEffect(() => { | ||
if (invalidKakaoToken) { | ||
alert('카카오 로그인이 만료되었습니다. 다시 로그인해주세요.') | ||
|
||
router.push(ROUTE.LOGIN) | ||
} | ||
}, [loginQuery.isError, invalidKakaoToken]) | ||
|
||
useEffect(() => { | ||
if (loginQuery.isSuccess) { | ||
setAccessToken(loginQuery.data.data.token) | ||
removeKakaoAccessToken() | ||
|
||
router.push(ROUTE.HOME) | ||
} | ||
}, [loginQuery.isSuccess]) | ||
|
||
if (invalidKakaoToken || !isNeedToRegister) { | ||
return null | ||
} | ||
|
||
return ( | ||
<main className='flex h-full flex-col items-center px-6 pb-16 pt-11'> | ||
<h1 className='text-2xl font-semibold'>프로필 생성</h1> | ||
<form className='w-full' onSubmit={handleSubmit(onSubmit)}> | ||
<div className='flex w-full flex-col gap-6'> | ||
<div className='mt-10 flex flex-col items-center'> | ||
<Image | ||
className='rounded-full bg-white' | ||
src={PROFILES.DEFAULT[selectedChampion]} | ||
width={187} | ||
height={187} | ||
alt='' | ||
/> | ||
|
||
<div className='mt-3 flex flex-col items-center gap-1'> | ||
<input | ||
className='mb-1 w-[84px] appearance-none border-0 border-b border-b-[#B8B8B8] bg-transparent p-0 text-center text-xl focus:ring-0' | ||
maxLength={4} | ||
defaultValue='' | ||
{...register('nickname', { | ||
required: true, | ||
maxLength: 4, | ||
pattern: /^[가-힣a-zA-Z0-9]*$/, | ||
onChange: (e) => { | ||
e.target.value = e.target.value.slice(0, 4) | ||
}, | ||
})} | ||
/> | ||
<span className='text-xs'>{watch('nickname').length >= 4 ? 4 : watch('nickname').length ?? 0} / 4</span> | ||
</div> | ||
</div> | ||
<div className='mx-auto grid w-fit grid-cols-3 gap-x-3 gap-y-4'> | ||
{Object.keys(PROFILES.DEFAULT).map((champion) => ( | ||
<button | ||
key={champion} | ||
onClick={() => { | ||
setSelectedChampion(champion as Champion) | ||
}} | ||
> | ||
<Image | ||
className='rounded-full bg-white' | ||
src={ | ||
selectedChampion === champion | ||
? PROFILES.SELECTED[champion as Champion] | ||
: PROFILES.DEFAULT[champion as Champion] | ||
} | ||
width={80} | ||
height={80} | ||
alt='' | ||
/> | ||
</button> | ||
))} | ||
</div> | ||
<button | ||
className='mt-28 flex h-14 w-full items-center justify-center rounded-[50px] bg-[#482BD9]' | ||
type='submit' | ||
> | ||
달 탐사 시작하기 | ||
</button> | ||
</div> | ||
</form> | ||
</main> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { useMutation, useQuery } from '@tanstack/react-query' | ||
import { type AxiosError } from 'axios' | ||
|
||
import { login, signUp } from '@/app/_service/auth' | ||
import { type Champion, type LoginResponse } from '@/app/_service/auth/auth.types' | ||
import { type ServerError, type ServerResponse } from '@/app/_service/core/api.types' | ||
|
||
const QUERY_KEY = { | ||
LOGIN: (accessToken: string) => ['login', accessToken], | ||
} | ||
|
||
export const useLoginQuery = ({ accessToken }: { accessToken: string }) => { | ||
return useQuery<ServerResponse<LoginResponse>, AxiosError<ServerError>>({ | ||
queryKey: QUERY_KEY.LOGIN(accessToken), | ||
queryFn: () => { | ||
return login({ accessToken }) | ||
}, | ||
enabled: Boolean(accessToken), | ||
}) | ||
} | ||
|
||
export const useSignUpMutation = () => { | ||
return useMutation({ | ||
mutationFn: ({ | ||
accessToken, | ||
nickname, | ||
champion, | ||
}: { | ||
accessToken: string | ||
nickname: string | ||
champion: Champion | ||
}) => { | ||
return signUp({ accessToken, nickname, champion }) | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
export const KAKAO = { | ||
// REST_API_KEY: '8cb6bb4a47d00e99bb5a038f9b6467fe', | ||
REST_API_KEY: 'df0059498e461a8b0c76d9b4d537dbaa', | ||
REDIRECT_URI: 'http://localhost:3000/oauth/callback/kakao', | ||
REDIRECT_URI: 'http://localhost:4000/oauth/callback/kakao', | ||
} |
Oops, something went wrong.