diff --git a/src/api/index.ts b/src/api/index.ts index 65e3a4b..c87e3c0 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -14,8 +14,8 @@ const createAxios = (): AxiosInstance => { return axios.create({ baseURL: `${BASE_URL}/api/v1`, headers: HEADERS }); }; -const createAxiosWithToken = (): AxiosInstance => { - const requestHTTP = axios.create({ baseURL: `${BASE_URL}/api/v1`, headers: HEADERS }); +const createAxiosWithToken = (version: string): AxiosInstance => { + const requestHTTP = axios.create({ baseURL: `${BASE_URL}/api/${version}`, headers: HEADERS, withCredentials: true }); return interceptors(requestHTTP); }; @@ -33,7 +33,25 @@ const createAxiosWithTokenInUpload = (): AxiosInstance => { export const axiosService = createAxios(); // With token -export const axiosWithToken = createAxiosWithToken(); +export const axiosWithToken = createAxiosWithToken('v1'); // With token export const axiosWithTokenInUpload = createAxiosWithTokenInUpload(); + +interface ApisType { + url: string; +} + +class Apis implements ApisType { + constructor(public url: string) { + this.url = url; + } + + async fetchUser(bodyData: bodyDataType) { + await createAxiosWithToken('v2').post(`/users/${this.url}`, bodyData); + } +} + +const api = (url: string) => new Apis(url); + +export default api; diff --git a/src/components/Login/useLogin.ts b/src/components/Login/useLogin.ts new file mode 100644 index 0000000..5ebac93 --- /dev/null +++ b/src/components/Login/useLogin.ts @@ -0,0 +1,38 @@ +import { useState } from 'react'; +import { useRouter } from 'next/router'; + +import { LoginRequestDataType } from '@/types/login'; +import { FetchDataType } from '@/types/fetchData'; + +import api from '@api'; +import { useMutation } from 'react-query'; +import { AxiosError } from 'axios'; + +export default function useLogin() { + const router = useRouter(); + const [loginErrorMessage, setLoginErrorMessage] = useState(''); + + const { mutate: userLogin } = useMutation((loginData: LoginRequestDataType) => api('login').fetchUser(loginData), { + onMutate: () => { + setLoginErrorMessage(''); + }, + onSuccess: () => { + router.push('/'); + }, + onError: (error: AxiosError) => { + if (error.response) { + const { code, status, detail } = error.response.data; + + if (status === 404) { + setLoginErrorMessage(detail); + } + + if (code === 400) { + setLoginErrorMessage('아이디 또는 비밀번호가 올바르지 않습니다.'); + } + } + }, + }); + + return { userLogin, loginErrorMessage }; +} diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index a42c3bb..25ea33b 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -6,15 +6,14 @@ import { useRouter } from 'next/router'; import { Button, Input, Title, Text } from '@components/Common'; import Layout from '@components/Layout/Layout'; +import useLogin from '@components/Login/useLogin'; + import * as Styled from '@components/Layout/LayoutStyle'; -import * as SignupStyle from '@components/Signup/SignupPageStyle'; import { EMAIL_VALIDATION } from '@constants/validation'; import { LoginRequestDataType } from '@/types/login'; import { FormRegisterType } from '@/types/signup'; -import { useLoginMutation } from '@api/queries/users'; - function LoginPage() { const router = useRouter(); @@ -26,36 +25,9 @@ function LoginPage() { const [emailValue, setEmailValue] = useState(''); const [passwordValue, setPasswordValue] = useState(''); - const [isFormErrorState, setIsFormErrorState] = useState(false); - const [emailErrorMessage, setEmailErrorMessage] = useState(''); + const [noDataErrorMessage, setNoDataErrorMessage] = useState(''); - const loginMutation = useLoginMutation({ - onMutate: () => { - setIsFormErrorState(false); - setEmailErrorMessage(''); - }, - onSuccess: (data) => { - const { accessToken, refreshToken } = data.data.data; - localStorage.setItem('accessToken', accessToken); - localStorage.setItem('refreshToken', refreshToken); - - router.push('/'); - }, - onError: (error) => { - if (error.response) { - const { code, status, detail } = error.response.data; - - setIsFormErrorState(true); - if (status === 404) { - setEmailErrorMessage(detail); - } - - if (code === 400) { - setEmailErrorMessage('아이디 또는 비밀번호가 올바르지 않습니다.'); - } - } - }, - }); + const { userLogin, loginErrorMessage } = useLogin(); const handleLoginChangeValue = useCallback( (e: ChangeEvent, type: string) => { @@ -74,11 +46,10 @@ function LoginPage() { const handleLoginSubmit = useCallback( (data: LoginRequestDataType) => { - setEmailErrorMessage(''); + setNoDataErrorMessage(''); if ((data.email === '' || data.password === '') && passwordValue === '') { - setIsFormErrorState(true); - setEmailErrorMessage('이메일 또는 비밀번호를 입력해 주세요.'); + setNoDataErrorMessage('이메일 또는 비밀번호를 입력해 주세요.'); return; } @@ -87,11 +58,17 @@ function LoginPage() { password: passwordValue || data.password, }; - loginMutation.mutate(loginData); + userLogin(loginData); }, - [emailValue, passwordValue, isFormErrorState, emailErrorMessage] + [emailValue, passwordValue, noDataErrorMessage] ); + const handleErrorMessage = useCallback(() => { + const hasErrorMessage = !!errors.email?.message || !!noDataErrorMessage || !!loginErrorMessage; + + return hasErrorMessage; + }, [errors, noDataErrorMessage, loginErrorMessage]); + const handleSignupButton = () => { router.push('/signup'); }; @@ -110,7 +87,7 @@ function LoginPage() { value={emailValue} changeEvent={(e) => handleLoginChangeValue(e, 'email')} placeholderText="이메일을 입력해 주세요." - hasErrorDisplay={isFormErrorState || !!errors.email?.message} + hasErrorDisplay={handleErrorMessage()} margin="1.2rem" /> @@ -121,10 +98,11 @@ function LoginPage() { value={passwordValue} changeEvent={(e) => handleLoginChangeValue(e, 'password')} placeholderText="비밀번호를 입력해 주세요." - hasErrorDisplay={isFormErrorState || !!errors.email?.message} + hasErrorDisplay={handleErrorMessage()} /> - {errors && {errors.email?.message}} - {isFormErrorState && {emailErrorMessage}} + {errors && {errors.email?.message}} + {noDataErrorMessage && {noDataErrorMessage}} + {loginErrorMessage && {loginErrorMessage}}