-
Notifications
You must be signed in to change notification settings - Fork 1
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
FE-66 🔀 회원가입 페이지 머지 요청 #72
Merged
Merged
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
74648e7
:lipstick: 회원가입 페이지 레이아웃 추가
jangmoonwon 8a437d1
:lipstick: 간편 로그인 로고 추가
jangmoonwon 9537b85
:lipstick: 회원가입 ui 추가
jangmoonwon 61098fb
Merge pull request #37 from epigram5-9/feat/FE-67
jangmoonwon eb34b5d
:sparkles: 회원가입 스키마 정의
jangmoonwon eaaf1cc
:heavy_plus_sign: 회원가입 페이지에 스키마 적용
jangmoonwon dfb693a
:lipstick: 에러 메시지 뜰 때 라벨, 인풋도 같은 에러 색깔 추가
jangmoonwon c1305fc
:memo: 유효성 검사를 통한 버튼의 비활성화 처리
jangmoonwon 91e1fff
:memo: 유효성 검사에 따른 인풋 테두리 색상 처리
jangmoonwon 03d62c5
Merge pull request #40 from epigram5-9/feat/FE-68
jangmoonwon bfd7d3b
:fire: AuthLayout 삭제
jangmoonwon 467a76c
:art: 회원가입 페이지 브라우저 확대시 ui 깨짐 수정
jangmoonwon bd48061
:truck: 정규표현식 네이밍 변경
jangmoonwon 1256f61
Merge pull request #48 from epigram5-9/fix/FE-66
jangmoonwon c3b2e06
:twisted_rightwards_arrows: Merge branch 'epic/FE-66' into merge/FE-66
jangmoonwon 36f4b58
Merge pull request #55 from epigram5-9/merge/FE-66
jangmoonwon 70d45e4
:sparkles: 회원가입 응답 데이터 스키마 정의
jangmoonwon f79b702
:sparkles: 회원가입 api 생성
jangmoonwon 8ba0103
:sparkles: useRegisterMutation hook 생성
jangmoonwon e5efa3e
:zap: 회원가입 폼에 mutaion hook 적용
jangmoonwon ca394cc
:sparkles: Toaster 컴포넌트 추가
jangmoonwon 4e9e01a
:sparkles: toast로 에러메시지 띄우기
jangmoonwon ea2264f
:zap: isAxiosError로 변경
jangmoonwon 8a35cf2
Merge pull request #69 from epigram5-9/fix/FE-69
jangmoonwon a367f41
Merge pull request #59 from epigram5-9/feat/FE-69
jangmoonwon 7c1f9c4
:twisted_rightwards_arrows: 메인 pr 최신화 및 confiict 수정
jangmoonwon 5785703
:twisted_rightwards_arrows: 충돌 해결
jangmoonwon a715986
Merge branch 'epic/FE-66' into merge/FE-66
jangmoonwon 9715918
:bug: postSignup 함수 추가
jangmoonwon 0762f98
:bug: postSignin 내보내는 방식 수정
jangmoonwon a45fdf4
:twisted_rightwards_arrows: conflict 수정
jangmoonwon 7e4eba6
:wrench: lint 수정
jangmoonwon b5227f6
Merge pull request #74 from epigram5-9/merge/FE-66
jangmoonwon 912b9ef
:twisted_rightwards_arrows: Merge branch 'epic/FE-66' into merge/FE-66
jangmoonwon ceaaeec
Merge pull request #87 from epigram5-9/merge/FE-66
jangmoonwon 192e06e
:recycle: 에러처리 로직 수정
jangmoonwon 3322aaa
Merge pull request #95 from epigram5-9/fix/FE-66
jangmoonwon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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,9 +1,12 @@ | ||
import type { PostSigninRequestType, PostSigninResponseType } from '@/schema/auth'; | ||
import type { PostSigninRequestType, PostSigninResponseType, PostSignUpRequestType, PostSignUpResponseType } from '@/schema/auth'; | ||
import httpClient from '.'; | ||
|
||
const postSignin = async (request: PostSigninRequestType): Promise<PostSigninResponseType> => { | ||
export const postSignin = async (request: PostSigninRequestType): Promise<PostSigninResponseType> => { | ||
const response = await httpClient.post('/auth/signIn', request); | ||
return response.data; | ||
}; | ||
|
||
export default postSignin; | ||
export const postSignup = async (request: PostSignUpRequestType): Promise<PostSignUpResponseType> => { | ||
const response = await httpClient.post('/auth/signUp', request); | ||
return response.data; | ||
}; |
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,77 @@ | ||
import { postSignup } from '@/apis/auth'; | ||
import { toast } from '@/components/ui/use-toast'; | ||
import { useMutation } from '@tanstack/react-query'; | ||
import { useRouter } from 'next/router'; | ||
import { isAxiosError } from 'axios'; | ||
|
||
const useRegisterMutation = () => { | ||
const router = useRouter(); | ||
|
||
return useMutation({ | ||
mutationFn: postSignup, | ||
onSuccess: (data) => { | ||
localStorage.setItem('accessToken', data.accessToken); | ||
localStorage.setItem('refreshToken', data.refreshToken); | ||
router.push('/'); | ||
}, | ||
onError: (error) => { | ||
if (isAxiosError(error)) { | ||
const { status, data } = error.response || {}; | ||
|
||
if (!status) return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ |
||
|
||
if (status === 400) { | ||
const errorMessage = data?.message || '잘못된 요청입니다. 입력 값을 확인해주세요.'; | ||
|
||
if (errorMessage.includes('이미 사용중인 이메일')) { | ||
toast({ | ||
description: '이미 사용중인 이메일입니다.', | ||
className: 'border-state-error text-state-error font-semibold', | ||
}); | ||
return; | ||
} | ||
|
||
toast({ | ||
description: errorMessage, | ||
className: 'border-state-error text-state-error font-semibold', | ||
}); | ||
return; | ||
} | ||
|
||
if (status === 500) { | ||
const errorMessage = data?.message || '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.'; | ||
|
||
// NOTE: swagger 문서에서 중복된 닉네임은 500에러와 함께 "Internal Server Error" 메시지로 응답 옴 | ||
if (errorMessage.includes('Internal Server Error')) { | ||
toast({ | ||
description: '이미 존재하는 닉네임입니다.', | ||
className: 'border-state-error text-state-error font-semibold', | ||
}); | ||
return; | ||
} | ||
|
||
toast({ | ||
description: errorMessage, | ||
className: 'border-state-error text-state-error font-semibold', | ||
}); | ||
return; | ||
} | ||
|
||
if (status >= 500) { | ||
toast({ | ||
description: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.', | ||
className: 'border-state-error text-state-error font-semibold', | ||
}); | ||
return; | ||
} | ||
|
||
toast({ | ||
description: '알 수 없는 오류가 발생했습니다. 잠시 후 다시 시도해주세요.', | ||
className: 'border-state-error text-state-error font-semibold', | ||
}); | ||
} | ||
}, | ||
}); | ||
}; | ||
|
||
export default useRegisterMutation; |
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,129 @@ | ||
import Image from 'next/image'; | ||
import Link from 'next/link'; | ||
import { zodResolver } from '@hookform/resolvers/zod'; | ||
import { PostSignUpRequest, PostSignUpRequestType } from '@/schema/auth'; | ||
import { useForm } from 'react-hook-form'; | ||
import { Input } from '@/components/ui/input'; | ||
import { Button } from '@/components/ui/button'; | ||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; | ||
import useRegisterMutation from '@/hooks/useRegisterMutation'; | ||
|
||
export default function SignUp() { | ||
const mutationRegister = useRegisterMutation(); | ||
|
||
const form = useForm<PostSignUpRequestType>({ | ||
resolver: zodResolver(PostSignUpRequest), | ||
mode: 'onBlur', | ||
defaultValues: { | ||
email: '', | ||
password: '', | ||
passwordConfirmation: '', | ||
nickname: '', | ||
}, | ||
}); | ||
|
||
return ( | ||
<div className='flex flex-col justify-center items-center bg-background-100 w-full min-h-screen'> | ||
<header className='h-full mb-[50px] md:mb-[60px]'> | ||
<Link href='/'> | ||
<Image src='/lg.svg' alt='logo' width={172} height={48} /> | ||
</Link> | ||
</header> | ||
<div className='w-full'> | ||
<Form {...form}> | ||
<form onSubmit={form.handleSubmit((values: PostSignUpRequestType) => mutationRegister.mutate(values))} className='flex flex-col items-center w-full h-full px-6'> | ||
<FormField | ||
control={form.control} | ||
name='email' | ||
render={({ field, fieldState }) => ( | ||
<FormItem className='flex flex-col w-full lg:max-w-[640px] md:max-w-[384px] space-y-0 md:mb-10 mb-5'> | ||
<FormLabel className={`md:mb-5 mb-4 font-pretendard lg:text-xl md:text-base sm:text-sm ${fieldState.invalid ? 'text-state-error' : 'text-blue-900'}`}>이메일</FormLabel> | ||
<FormControl> | ||
<Input | ||
type='text' | ||
placeholder='이메일' | ||
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`} | ||
{...field} | ||
/> | ||
</FormControl> | ||
<FormMessage className='flex justify-end text-[13px] text-state-error' /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name='password' | ||
render={({ field, fieldState }) => ( | ||
<FormItem className='flex flex-col w-full lg:max-w-[640px] md:max-w-[384px] space-y-0 md:mb-4 mb-[10px]'> | ||
<FormLabel className={`md:mb-5 mb-4 font-pretendard lg:text-xl md:text-base sm:text-sm ${fieldState.invalid ? 'text-state-error' : 'text-blue-900'}`}>비밀번호</FormLabel> | ||
<FormControl> | ||
<Input | ||
type='password' | ||
placeholder='비밀번호' | ||
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`} | ||
{...field} | ||
/> | ||
</FormControl> | ||
<FormMessage className='flex justify-end text-[13px] text-state-error' /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name='passwordConfirmation' | ||
render={({ field, fieldState }) => ( | ||
<FormItem className='flex flex-col w-full lg:max-w-[640px] md:max-w-[384px] space-y-0 md:mb-10 mb-5'> | ||
<FormControl> | ||
<Input | ||
type='password' | ||
placeholder='비밀번호 확인' | ||
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`} | ||
{...field} | ||
/> | ||
</FormControl> | ||
<FormMessage className='flex justify-end text-[13px] text-state-error' /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name='nickname' | ||
render={({ field, fieldState }) => ( | ||
<FormItem className='flex flex-col w-full lg:max-w-[640px] md:max-w-[384px] md:mb-10 mb-[30px] space-y-0'> | ||
<FormLabel className={`md:mb-5 mb-4 font-pretendard lg:text-xl md:text-base sm:text-sm ${fieldState.invalid ? 'text-state-error' : 'text-blue-900'}`}>닉네임</FormLabel> | ||
<FormControl> | ||
<Input | ||
type='text' | ||
placeholder='닉네임' | ||
className={`lg:h-16 h-11 px-4 lg:text-xl md:text-base placeholder-blue-400 rounded-xl bg-blue-200 font-pretendard ${fieldState.invalid ? 'border-2 border-state-error' : ''}`} | ||
{...field} | ||
/> | ||
</FormControl> | ||
<FormMessage className='flex justify-end text-[13px] text-state-error' /> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button | ||
disabled={!form.formState.isValid} | ||
type='submit' | ||
className={`w-full lg:max-w-[640px] md:max-w-[384px] lg:h-16 h-11 md:mb-[60px] mb-[50px] bg-black-500 font-pretendard text-white lg:text-xl md:text-base rounded-xl ${!form.formState.isValid ? 'bg-blue-300' : 'bg-black-500'}`} | ||
> | ||
가입하기 | ||
</Button> | ||
</form> | ||
</Form> | ||
</div> | ||
<div className='flex justify-center gap-4'> | ||
<Button type='button' className='md:size-[60px] p-0'> | ||
<Image src='/logo-naver.svg' alt='logo-naver' width={60} height={60} className='md:size-[60px] size-10' /> | ||
</Button> | ||
<Button type='button' className='md:size-[60px] p-0'> | ||
<Image src='/logo-google.svg' alt='logo-google' width={60} height={60} className='md:size-[60px] size-10' /> | ||
</Button> | ||
<Button type='button' className='md:size-[60px] p-0'> | ||
<Image src='/logo-kakao.svg' alt='logo-kakao' width={60} height={60} className='md:size-[60px] size-10' /> | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
} |
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.