Skip to content
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 ✨ 회원가입 페이지 api #59

Merged
merged 8 commits into from
Jul 25, 2024
Merged
11 changes: 11 additions & 0 deletions src/apis/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { PostSignUpRequestType, PostAuthResponseType } from '@/schema/auth';
import httpClient from '.';

// TODO: signin, signup 단어가 비슷해 login, register로 바꿀 예정

const postSignup = async (request: PostSignUpRequestType): Promise<PostAuthResponseType> => {
const response = await httpClient.post('/auth/signUp', request);
return response.data;
};

export default postSignup;
52 changes: 52 additions & 0 deletions src/hooks/useRegisterMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
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)) {
toast({
description: '네트워크 오류가 발생했습니다. 인터넷 연결을 확인해주세요.',
className: 'border-state-error text-state-error font-semibold',
});
return;
}

const { status } = error.response || {};

if (status === 400) {
toast({
description: '이미 사용중인 이메일입니다.',
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;
2 changes: 2 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import '@/styles/globals.css';
import type { AppProps } from 'next/app';
import { HydrationBoundary, QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import Toaster from '@/components/ui/toaster';

export default function App({ Component, pageProps }: AppProps) {
const [queryClient] = React.useState(() => new QueryClient());
return (
<QueryClientProvider client={queryClient}>
<HydrationBoundary state={pageProps.dehydratedState}>
<Component {...pageProps} />
<Toaster />
</HydrationBoundary>
<ReactQueryDevtools />
</QueryClientProvider>
Expand Down
5 changes: 4 additions & 1 deletion src/pages/auth/SignUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ 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',
Expand All @@ -28,7 +31,7 @@ export default function SignUp() {
</header>
<div className='w-full'>
<Form {...form}>
<form className='flex flex-col items-center w-full h-full px-6'>
<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'
Expand Down
21 changes: 20 additions & 1 deletion src/schema/auth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import z from 'zod';
import * as z from 'zod';

const PWD_VALIDATION_REGEX = /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{8,}$/;

export const PostSignUpRequest = z
.object({
email: z.string().min(1, { message: '이메일은 필수 입력입니다.' }).email({ message: '이메일 형식으로 작성해 주세요.' }),
Expand All @@ -17,4 +18,22 @@ export const PostSignUpRequest = z
path: ['passwordConfirmation'],
});

const User = z.object({
id: z.number(),
email: z.string().email(),
nickname: z.string(),
teamId: z.string(),
updatedAt: z.coerce.date(),
createdAt: z.coerce.date(),
image: z.string(),
});

// TODO: 나중에 signin, signup의 response가 같아 같은 이름으로 통일 할 예정
export const PostAuthResponse = z.object({
accessToken: z.string(),
refreshToken: z.string(),
user: User,
});

export type PostSignUpRequestType = z.infer<typeof PostSignUpRequest>;
export type PostAuthResponseType = z.infer<typeof PostAuthResponse>;
Loading