Skip to content

Commit

Permalink
Merge pull request #303 from Bamdoliro/develop
Browse files Browse the repository at this point in the history
Release - user v1.1.0
  • Loading branch information
SEOKKAMONI authored Aug 22, 2023
2 parents a4ceb6a + 6c63d91 commit 3bbee65
Show file tree
Hide file tree
Showing 26 changed files with 466 additions and 358 deletions.
4 changes: 2 additions & 2 deletions apps/user/src/apis/token/refresh.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TOKEN, ROUTES } from '@/constants/common/constant';
import { ROUTES, TOKEN } from '@/constants/common/constant';
import { maru } from '../instance/instance';
import { Storage } from '../storage/storage';

Expand All @@ -9,7 +9,7 @@ const refreshToken = async () => {
'Refresh-Token': `${Storage.getItem(TOKEN.REFRESH)}`,
},
});
Storage.setItem(TOKEN.ACCESS, data.accessToken);
Storage.setItem(TOKEN.ACCESS, data.data.accessToken);
} catch {
window.location.href = ROUTES.LOGIN;
alert('다시 로그인 해주세요');
Expand Down
29 changes: 28 additions & 1 deletion apps/user/src/app/form/보호자정보/보호자정보.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FindAddressModal, FormController } from '@/components/form';
import { FormLayout } from '@/layouts';
import { useFormValueStore } from '@/store';
import { ButtonInput, Column, Input, Row } from '@maru/ui';
import { ButtonInput, Column, Input, RadioGroup, Row } from '@maru/ui';
import { useOverlay } from '@toss/use-overlay';
import styled from 'styled-components';
import { useCTAButton, useInput } from './보호자정보.hooks';
Expand Down Expand Up @@ -53,6 +53,33 @@ const 보호자정보 = () => {
isError={form.parent.address.length > 100}
errorMessage="100자 이하여야 합니다."
/>
<Row justifyContent="flex-start" alignItems="center">
<RadioGroup
label="보호자 관계"
value={form.parent.relation}
onChange={handle보호자정보DataChange}
name="relation"
list={[
{ label: '부', value: '아빠' },
{ label: '모', value: '엄마' },
{
label: '기타',
value: '기타',
checked:
form.parent.relation !== '아빠' &&
form.parent.relation !== '엄마',
},
]}
/>
</Row>
{form.parent.relation !== '아빠' && form.parent.relation !== '엄마' && (
<Input
value={form.parent.relation}
onChange={handle보호자정보DataChange}
name="relation"
/>
)}

<Row gap={48}>
<Input
name="detailAddress"
Expand Down
13 changes: 2 additions & 11 deletions apps/user/src/app/form/성적입력/성적입력.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import { useSaveFormMutation } from '@/services/form/mutations';
import {
useSetFormStepStore,
useNewSubjectValueStore,
useSubjectValueStore,
useFormValueStore,
} from '@/store';
import { useFormValueStore, useSetFormStepStore } from '@/store';

export const useCTAButton = () => {
const form = useFormValueStore();
const setFormStep = useSetFormStepStore();
const newSubjectList = useNewSubjectValueStore();
const subjectList = useSubjectValueStore();
const { saveFormMutate } = useSaveFormMutation();

const studentSubjectList = [...subjectList, ...newSubjectList].map(({ id, ...rest }) => rest);

const handleNextButtonClick = () => {
setFormStep('자기소개서');
saveFormMutate({ ...form, grade: { ...form.grade, subjectList: studentSubjectList } });
saveFormMutate(form);
};

const handlePreviousButtonClick = () => {
Expand Down
401 changes: 212 additions & 189 deletions apps/user/src/app/form/전형선택/전형선택.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const useCheckFilledForm = () => {

if (
filledApplicantFieldsCount === 5 &&
filledParentFieldsCount === 5 &&
filledParentFieldsCount === 6 &&
filledEducationFieldsCount === 8 &&
filledTypeFieldsCount === 1 &&
filledDocumentFieldsCount === 2
Expand Down
5 changes: 2 additions & 3 deletions apps/user/src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
'use client';

import { ROUTES } from '@/constants/common/constant';
import { AppLayout } from '@/layouts';
import { IconArrowRight } from '@maru/icon';
import { color, font } from '@maru/theme';
import { Button, Column, Input, PreviewInput } from '@maru/ui';
import { flex } from '@maru/utils';
import Image from 'next/image';
import { useCTAButton, useInput, useLoginAction } from './login.hooks';
import styled from 'styled-components';
import { useCTAButton, useInput, useLoginAction } from './login.hooks';

const LoginPage = () => {
const { handleGoSingUpPageButtonClick, handleGoMainPageButtonClick } = useCTAButton();
Expand All @@ -31,7 +30,7 @@ const LoginPage = () => {
<Column gap="36px" width="100%">
<Column gap="24px">
<Input
label="아이디"
label="이메일"
width="100%"
name="email"
onChange={handleLoginUserDataChange}
Expand Down
8 changes: 6 additions & 2 deletions apps/user/src/app/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const SignUpPage = () => {
name="name"
placeholder="이름을 입력해주세요."
onChange={handleJoinUserDataChange}
isError={joinUserData.name.length === 0}
errorMessage="필수값입니다."
/>
<ButtonInput
label="이메일 인증"
Expand All @@ -61,17 +63,17 @@ const SignUpPage = () => {
label="인증코드"
width="100%"
maxLength={6}
errorMessage="발송된 이메일의 인증번호를 입력해주세요."
name="code"
onChange={handleJoinUserDataChange}
timerTime={timerTime}
setTimerTime={setTimerTime}
isError={joinUserData.code.length < 6}
errorMessage="발송된 이메일의 인증번호를 입력해주세요."
/>
)}
<PreviewInput
label="비밀번호"
width="100%"
errorMessage="8~16자의 영문 대소문자, 숫자, 특수문자만 가능합니다."
name="password"
onChange={handleJoinUserDataChange}
/>
Expand All @@ -80,6 +82,8 @@ const SignUpPage = () => {
width="100%"
name="password_confirm"
onChange={handleJoinUserDataChange}
isError={joinUserData.password !== joinUserData.password_confirm}
errorMessage="비밀번호가 맞지 않습니다."
/>
</Column>
{/* 이용약관 동의 */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const CertificateCalculator = () => {
},
}));
}
console.log(form);
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useNewSubjectStore, useSubjectStore } from '@/store';
import { useNewSubjectStore, useSetFormStore, useSubjectStore } from '@/store';
import { Subject } from '@/types/form/client';
import { color, font } from '@maru/theme';
import { Button, Column } from '@maru/ui';
Expand All @@ -12,6 +12,7 @@ import NewGradeCalculatorItem from './NewGradeCalculatorItem/NewGradeCalculatorI
const GradeCalculator = () => {
const [newSubjectList, setNewSubjectList] = useNewSubjectStore();
const [subjectList, setSubjectList] = useSubjectStore();
const setForm = useSetFormStore();
const footerRef = useRef<HTMLDivElement>(null);
const isMount = useRef(true);

Expand All @@ -35,6 +36,14 @@ const GradeCalculator = () => {
if (newSubjectList.length) footerRef.current?.scrollIntoView();
}, [newSubjectList]);

useEffect(() => {
const studentSubjectList = [...subjectList, ...newSubjectList].map(
({ id, ...rest }) => rest,
);

setForm((prev) => ({ ...prev, grade: { ...prev.grade, subjectList: studentSubjectList } }));
}, [newSubjectList, subjectList]);

return (
<StyledGradeCalculator>
<Desc>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const ProfileUploader = () => {
</Button>
)}
<Desc>
20MB 이하, 3개월 이내의
10MB 이하, 3개월 이내의
<br />
3x4 cm 증명사진
</Desc>
Expand Down
1 change: 1 addition & 0 deletions apps/user/src/constants/form/initial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const FORM: Form = {
zoneCode: '',
address: '',
detailAddress: '',
relation: '',
},
education: {
graduationType: 'EXPECTED',
Expand Down
1 change: 1 addition & 0 deletions apps/user/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as useApiError } from './useApiError';
export { default as useUser } from './useUser';
27 changes: 27 additions & 0 deletions apps/user/src/hooks/useApiError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { AxiosError, isAxiosError } from 'axios';

type ErrorStatus = 400 | 401 | 402 | 403 | 404 | 407 | 408 | 409 | 429 | 500;

const errorMessages: { [key in ErrorStatus]?: string } = {
403: '유저의 권한이 없습니다.',
429: '너무 많이 요청하였습니다. 조금 뒤 다시 이용해주세요.',
500: '서버에 알 수 없는 오류가 발생하였습니다.',
};

const useApiError = () => {
const handleError = (error: AxiosError) => {
let errorMessage = '';
if (isAxiosError(error)) {
const status = error.status as ErrorStatus;
const message = error.message;
errorMessage = message ?? errorMessages[status];
} else {
errorMessage = '알 수 없는 오류가 발생하였습니다.';
}
errorMessage && alert(errorMessage);
};

return { handleError };
};

export default useApiError;
8 changes: 3 additions & 5 deletions apps/user/src/mocks/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { noticeHandlers } from "./notice";
import { mainHandlers } from "./main";
import { faqHandlers } from "./faq";
import { faqHandlers } from './faq';
import { mainHandlers } from './main';
import { noticeHandlers } from './notice';

export const handlers = [...noticeHandlers, ...mainHandlers, ...faqHandlers];

console.log(handlers);
2 changes: 1 addition & 1 deletion apps/user/src/services/QueryClientProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { QueryClientProvider as MaruQueryClientProvider, QueryClient } from '@tanstack/react-query';
import { QueryClient, QueryClientProvider as MaruQueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ReactNode, useState } from 'react';

Expand Down
34 changes: 12 additions & 22 deletions apps/user/src/services/auth/mutations.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Storage } from '@/apis/storage/storage';
import { ROUTES, TOKEN } from '@/constants/common/constant';
import { useApiError } from '@/hooks';
import { PostJoinAuthReq, PostLoginAuthReq } from '@/types/auth/remote';
import { useMutation } from '@tanstack/react-query';
import { AxiosError, AxiosResponse } from 'axios';
import { AxiosResponse } from 'axios';
import { useRouter } from 'next/navigation';
import { deleteLogoutUser, postJoinUser, postLoginUser, postRequestEmail } from './api';

export const useLoginUserMutation = ({ email, password }: PostLoginAuthReq) => {
const router = useRouter();
const { handleError } = useApiError();

const { mutate: loginUserMutate, ...restMutation } = useMutation({
mutationFn: () => postLoginUser({ email, password }),
Expand All @@ -17,61 +19,49 @@ export const useLoginUserMutation = ({ email, password }: PostLoginAuthReq) => {
Storage.setItem(TOKEN.REFRESH, refreshToken);
router.push(ROUTES.MAIN);
},
onError: (err: AxiosError) => {
if (err.code === 'BAD_REQUEST') {
alert('아이디와 패스워드를 다 입력해주세요.');
return;
}
alert(err.message);
},
onError: handleError,
});

return { loginUserMutate, ...restMutation };
};

export const useJoinUserMutation = ({ email, name, code, password }: PostJoinAuthReq) => {
const router = useRouter();
const { handleError } = useApiError();

const { mutate: joinUserMutate, ...restMutation } = useMutation({
mutationFn: () => postJoinUser({ email, name, code, password }),
onSuccess: () => {
alert('회원가입 성공');
router.push(ROUTES.LOGIN);
},
onError: (err: AxiosError) => {
if (err.code === 'BAD_REQUEST') {
alert('다시 한번 확인해주세요.');
return;
}
alert(err.message);
},
onError: handleError,
});

return { joinUserMutate, ...restMutation };
};

export const useRequestEmailMutation = (email: string) => {
const { handleError } = useApiError();

const { mutate: requestEmailMutate, ...restMutation } = useMutation({
mutationFn: () => postRequestEmail(email),
onError: (err: AxiosError) => {
if (err.code === 'BAD_REQUEST') {
alert('올바른 형식의 이메일이어야 합니다.');
return;
}
alert('메일 전송에 실패했습니다.');
},
onError: handleError,
});

return { requestEmailMutate, ...restMutation };
};

export const useLogoutUserMutation = () => {
const { handleError } = useApiError();

const { mutate: logoutUserMutate, ...restMutation } = useMutation({
mutationFn: deleteLogoutUser,
onSuccess: () => {
localStorage.clear();
window.location.href = ROUTES.MAIN;
},
onError: handleError,
});

return { logoutUserMutate, ...restMutation };
Expand Down
Loading

0 comments on commit 3bbee65

Please sign in to comment.