Skip to content

Commit

Permalink
Merge pull request #34 from YAPP-Github/refactor/YS-224
Browse files Browse the repository at this point in the history
[REFACTOR] zod 활용하여 회원가입 validation 적용
  • Loading branch information
rbgksqkr authored Feb 1, 2025
2 parents c55b030 + 017b8f9 commit 5456f3b
Show file tree
Hide file tree
Showing 51 changed files with 969 additions and 625 deletions.
2 changes: 1 addition & 1 deletion src/apis/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from 'axios';

import { CustomAxiosError } from './type';
import { updateAccessToken } from './login';
import { CustomAxiosError } from './type';

export const API = axios.create({
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
Expand Down
7 changes: 4 additions & 3 deletions src/apis/login.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { API } from './config';

import { ParticipantJoinParams, ResearcherJoinParams } from '@/app/join/JoinPage.types';
import { API_URL } from '@/constants/url';
import { ParticipantJoinSchemaType } from '@/schema/join/ParticipantJoinSchema';
import { ResearcherJoinSchemaType } from '@/schema/join/ResearcherJoinSchema';

interface UnivAuthCodeResponse {
isSuccess: boolean;
Expand Down Expand Up @@ -85,13 +86,13 @@ export const verifyUnivAuthCode = async (univEmail: string, inputCode: string) =
return res.data;
};

export const joinResearcher = async (params: ResearcherJoinParams) => {
export const joinResearcher = async (params: ResearcherJoinSchemaType) => {
const res = await API.post<JoinResponse>(API_URL.joinResearcher, { ...params });

return res.data;
};

export const joinParticipant = async (params: ParticipantJoinParams) => {
export const joinParticipant = async (params: ParticipantJoinSchemaType) => {
const res = await API.post<JoinResponse>(API_URL.joinParticipant, { ...params });

return res.data;
Expand Down
16 changes: 8 additions & 8 deletions src/app/home/components/PostContainer/PostContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import {
totalPostCount,
} from './PostContainer.styles';
import { filterParticipantInfo } from '../../home.utils';
import { useUserInfoQuery } from '../../hooks/useUserInfoQuery';
import useUserInfo from '../../hooks/useUserInfo';

import { PostListParams } from '@/apis/post';
import JoinCheckbox from '@/app/join/components/JoinEmailStep/JoinCheckboxContainer/JoinCheckbox/JoinCheckbox';
import JoinCheckbox from '@/app/join/components/JoinCheckboxContainer/JoinCheckbox/JoinCheckbox';

// TODO: [유저 정보 적용된 필터링 구현]
// 1. role을 가져옴 (sessionStorage 또는 Context)
Expand All @@ -25,15 +25,15 @@ import JoinCheckbox from '@/app/join/components/JoinEmailStep/JoinCheckboxContai
// 3-1. 참여자가 아닐 경우(연구자, 비회원)에는 자동 적용 필터 X
// FIXME: 참여자일 경우에는 쿼리를 2번 호출함
// FIXME: 4. 선택된 filter가 각각 관리되고 있는데, PostContainer의 filters 값으로 같이 관리하기

const PostContainer = () => {
const role = sessionStorage.getItem('role') || '';
const { data: userInfoData } = useUserInfoQuery(role);
const participantInfo = filterParticipantInfo(userInfoData);
const { userInfo } = useUserInfo();
const participantInfo = filterParticipantInfo(userInfo);

const [filters, setFilters] = useState<Pick<PostListParams, 'recruitStatus'>>({
recruitStatus: 'ALL',
});
const { data } = usePostListQuery(filters);
const { data: postListData } = usePostListQuery(filters);

const isRecruiting = filters.recruitStatus === 'OPEN';

Expand Down Expand Up @@ -75,8 +75,8 @@ const PostContainer = () => {
/>
</div>
<div css={postCardContainer}>
<span css={totalPostCount}>{data?.content.length}</span>
<PostCardList postList={data?.content} />
<span css={totalPostCount}>{postListData?.content.length}</span>
<PostCardList postList={postListData?.content} />
</div>
</div>
);
Expand Down
18 changes: 18 additions & 0 deletions src/app/home/hooks/useParticipantInfoQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from '@tanstack/react-query';

import { getParticipantInfo } from '@/apis/login';

interface useParticipantInfoQueryProps {
enabled: boolean;
}

const useParticipantInfoQuery = ({ enabled }: useParticipantInfoQueryProps) => {
return useQuery({
queryKey: ['participantInfo'],
queryFn: getParticipantInfo,
enabled,
retry: 1,
});
};

export default useParticipantInfoQuery;
18 changes: 18 additions & 0 deletions src/app/home/hooks/useResearcherInfoQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from '@tanstack/react-query';

import { getResearcherInfo } from '@/apis/login';

interface useResearcherInfoQueryProps {
enabled: boolean;
}

const useResearcherInfoQuery = ({ enabled }: useResearcherInfoQueryProps) => {
return useQuery({
queryKey: ['researcherInfo'],
queryFn: getResearcherInfo,
enabled,
retry: 1,
});
};

export default useResearcherInfoQuery;
22 changes: 22 additions & 0 deletions src/app/home/hooks/useUserInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import useParticipantInfoQuery from './useParticipantInfoQuery';
import useResearcherInfoQuery from './useResearcherInfoQuery';

import { ROLE } from '@/constants/config';
import useSessionStorage from '@/hooks/useSessionStorage';

const useUserInfo = () => {
const role = useSessionStorage('role');
const isParticipant = role === ROLE.participant;
const isResearcher = role === ROLE.researcher;

const participantQuery = useParticipantInfoQuery({ enabled: isParticipant });
const researcherQuery = useResearcherInfoQuery({ enabled: isResearcher });

return {
userInfo: isParticipant ? participantQuery.data : researcherQuery.data,
isLoading: participantQuery.isLoading || researcherQuery.isLoading,
isError: participantQuery.isError || researcherQuery.isError,
};
};

export default useUserInfo;
22 changes: 0 additions & 22 deletions src/app/home/hooks/useUserInfoQuery.ts

This file was deleted.

6 changes: 6 additions & 0 deletions src/app/join/JoinPage.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@ export const JOIN_SUB_REGION = JOIN_REGION.reduce(
},
{},
);

export const STEP = {
email: 'email',
info: 'info',
success: 'success',
} as const;
29 changes: 0 additions & 29 deletions src/app/join/JoinPage.types.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
export interface ResearcherJoinParams {
provider: 'NAVER' | 'GOOGLE';
oauthEmail: string;
contactEmail: string;
univEmail: string;
name: string;
univName: string;
major: string;
labInfo: string;
}

// TODO: 타입 좁히기
// birthDate: '2025-01-22';
// region 타입, area 타입
export type Gender = 'MALE' | 'FEMALE' | 'ALL';
export type MatchType = 'ONLINE' | 'OFFLINE' | 'ALL';

export interface ParticipantJoinParams {
provider: 'NAVER' | 'GOOGLE';
oauthEmail: string;
contactEmail: string;
name: string;
gender: Gender;
birthDate: string;
basicAddressInfo: {
region: string;
area: string;
};
additionalAddressInfo: {
region: string;
area: string;
};
matchType?: MatchType;
}

export interface ServiceAgreeCheck {
isTermOfService: boolean;
isPrivacy: boolean;
Expand Down
4 changes: 4 additions & 0 deletions src/app/join/JoinPage.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export const getProvider = (email: string): 'GOOGLE' | 'NAVER' => {
const GOOGLE_DOMAINS = 'gmail.com';
const NAVER_DOMAINS = 'naver.com';

if (!email || !email.includes('@')) {
throw new Error('잘못된 이메일 형식입니다.');
}

const targetDomain = email.split('@')[1].toLowerCase();

if (targetDomain.includes(GOOGLE_DOMAINS)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
labelWrapper,
requiredCheckboxText,
} from './JoinCheckbox.styles';
import { tipAlert, tipWrapper } from '../../../JoinInput/JoinInput.styles';
import { tipAlert, tipWrapper } from '../../JoinInput/JoinInput.styles';

import Icon from '@/components/Icon';
import theme from '@/styles/theme';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ServiceAgreeCheck } from '../../JoinPage.types';
import JoinCheckbox from './JoinCheckbox/JoinCheckbox';
import { termContainer } from './JoinCheckboxContainer.styles';
import { ServiceAgreeCheck } from '../../../JoinPage.types';

interface JoinCheckboxContainerProps {
serviceAgreeCheck: ServiceAgreeCheck;
Expand Down
77 changes: 0 additions & 77 deletions src/app/join/components/JoinEmailStep/JoinEmailStep.tsx

This file was deleted.

Loading

0 comments on commit 5456f3b

Please sign in to comment.