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

10주차 코드리뷰 #124

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1 @@
# 🍪 내가 먹은 쿠키 - 18조 FE

## 🙋‍♂️ 9주차 코드리뷰 질문

컴포넌트에는 개발하면서 페이지 내에서 임시로 만들어 사용하는 컴포넌트가 있고, 공통 컴포넌트로 개발해둔 것이 있고, 라이브러리에서 가져와서 사용하는 컴포넌트가 있습니다. 그런데 이런 컴포넌트를 필요에 따라 혼용해서 사용하니까 헷갈리기도 합니다. 이런 컴포넌트 사용에 있어서 지키면 좋을 규칙같은 게 있을까요?

예를 들어 아래에서 Section은 제가 해당 컴포넌트 내에서만 사용하려고 만든 컴포넌트이고, Typo는 공통컴포넌트로 이전에 개발한 컴포넌트입니다.
```tsx
<Section>
<Typo bold element="h3" size="20px" style={{ marginBottom: '24px' }}>
내가 지원한 공고
</Typo>
{myRecruitList && <MyRecruitList myRecruitList={myRecruitList} />}
</Section>
</InnerContainer>
</Layout>
);
}

const Section = styled.div`
width: 100%;
direction: column;
align-items: center;
margin-bottom: 52px;
`;

2,307 changes: 567 additions & 1,740 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@
"axios": "^1.7.7",
"buffer": "^6.0.3",
"csstype": "^3.1.3",
"i18next": "^23.16.4",
"jquery": "^3.7.1",
"prop-types": "^15.8.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.1.2",
"react-hook-form": "^7.53.0",
"react-i18next": "^15.1.0",
"react-router-dom": "^6.26.2",
"react-signature-canvas": "^1.0.6",
"zustand": "^4.5.5"
Expand Down
1 change: 1 addition & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AppProviders from '@components/providers/index.provider';
import { Outlet } from 'react-router-dom';
import '@/assets/translator/i18n';

function App() {
return (
Expand Down
20 changes: 17 additions & 3 deletions src/apis/apiPath.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const BASE_URL = '/api';

export const APIPath = {
postRegister: `${BASE_URL}/register`,
postOAuth: `${BASE_URL}/oauth`,
postNotice: `${BASE_URL}/recruitments`,
getSlides: `${BASE_URL}/slides`,
getRecruitments: `${BASE_URL}/recruitments/:filter`,
allApplication: `${BASE_URL}/application/all`,
signEmployeeContract: `${BASE_URL}/contract/employee`,
makeContract: `${BASE_URL}/contract`,
Expand All @@ -14,16 +18,26 @@ export const APIPath = {
getForeigner: `${BASE_URL}/visa/:userId`,
registerVisa: `${BASE_URL}/visa`,
registerCompany: `${BASE_URL}/company`,
apply: '/api/application/',
recruitmentsDetail: '/api/recruitments/:postId',
apply: `${BASE_URL}/application/:recruitmentId`,
resume: `${BASE_URL}/resumes`,
recruitmentsDetail: '/api/recruitments/:recruitmentId',
getApplicantProfile: '/api/resumes/:resumeId/:applyId',
closeRecruitment: `${BASE_URL}/recruitment/hiringClose/:recruitmentId`,
requiredFieldCheck: `${BASE_URL}/application`,
};

export const getDynamicAPIPath = {
downloadContract: (applyId: number) => APIPath.downloadContract.replace(':applyId', applyId.toString()),
apply: (recruitmentId: number) => APIPath.apply.replace(':recruitmentId', recruitmentId.toString()),
getContract: (applyId: number) => APIPath.getContract.replace(':applyId', applyId.toString()),
getMyRecruitments: (companyId: number) => APIPath.getMyRecruitments.replace(':companyId', companyId.toString()),
getMyApplicants: (recruitmentId: number) =>
APIPath.getMyApplicants.replace(':recruitmentId', recruitmentId.toString()),
getForeigner: (userId: number) => APIPath.getForeigner.replace(':userId', userId.toString()),
recruitmentsDetail: (postId: string) => APIPath.recruitmentsDetail.replace(':postId', postId.toString()),
recruitmentsDetail: (postId: number) => APIPath.recruitmentsDetail.replace(':recruitmentId', postId.toString()),
getApplicantProfile: (resumeId: number, applyId: number) =>
APIPath.getApplicantProfile.replace(':resumeId', resumeId.toString()).replace(':applyId', applyId.toString()),
closeRecruitment: (recruitmentId: number) =>
APIPath.closeRecruitment.replace(':recruitmentId', recruitmentId.toString()),
getRecruitments: (filter: string) => APIPath.getRecruitments.replace(':filter', filter),
};
19 changes: 19 additions & 0 deletions src/apis/applicants/hooks/useGetProfileInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getDynamicAPIPath } from '@/apis/apiPath';
import { clientInstance } from '@/apis/instance';
import { useQuery } from '@tanstack/react-query';

type IdProps = {
resumeId: number;
applyId: number;
};

export const getProfileInfo = async ({ resumeId, applyId }: IdProps) => {
const response = await clientInstance.get(getDynamicAPIPath.getApplicantProfile(resumeId, applyId));
return response.data;
};
Comment on lines +10 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 친구는 export 를 해주지 않아도 무방해보여요.


export const useGetProfileInfo = ({ resumeId, applyId }: IdProps) =>
useQuery({
queryKey: [getDynamicAPIPath.getApplicantProfile(resumeId, applyId)],
queryFn: () => getProfileInfo({ resumeId, applyId }),
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const recruitment = {
recruitmentId: 1,
image: CompanyImage,
koreanTitle: '쿠팡 유성점에서 아르바이트 모집합니다.',
vietnameseTitle: '',
vietnameseTitle: 'Coupang đang tuyển dụng làm việc bán thời gian tại chi nhánh Yuseong.',
companyName: '쿠팡 유성점',
salary: 50000000,
workHours: '',
Expand Down
2 changes: 1 addition & 1 deletion src/apis/applicants/mocks/foreignerMockHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIPath } from '@/apis/apiPath';
import { foreigner } from '@/features/applicants/ApplicantList/ContractModal/ContractModal.mock';
import { foreigner } from './foreigner.mock';
import { http, HttpResponse } from 'msw';

export const foreignerMockHandler = [http.get(APIPath.getForeigner, () => HttpResponse.json(foreigner))];
18 changes: 18 additions & 0 deletions src/apis/applicants/mocks/getApplicantProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { http, HttpResponse } from 'msw';
import { APIPath } from '@/apis/apiPath';

const mockData = {
applicantName: '임세빈',
address: '충남대학교',
phoneNumber: '010-1111-1111',
career: `카페에서 1년 알바했습니다. 클럽에서 30년 근무했습니다.`,
koreanLanguageLevel: '고급',
introduction: `맡은 업무에 항상 최선을 다하는 인재입니다. 안녕하세용안녕하세용안녕하세용안녕하세용안녕하세용안녕하세용`,
motivation: '돈',
};

export const getProfileInfoHandler = [
http.get(APIPath.getApplicantProfile, () => {
return HttpResponse.json(mockData);
}),
];
2 changes: 1 addition & 1 deletion src/apis/applicants/mocks/myApplicantsMockHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIPath } from '@/apis/apiPath';
import { applicantList } from '@/pages/applicants/Applicants.mock';
import { applicantList } from './applicants.mock';
import { http, HttpResponse } from 'msw';

export const myApplicantsMockHandler = [http.get(APIPath.getMyApplicants, () => HttpResponse.json(applicantList))];
4 changes: 2 additions & 2 deletions src/apis/apply/postApply.mock.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { http, HttpResponse } from 'msw';
import { getApply } from '../apply/useApplyHook';
import { APIPath } from '@/apis/apiPath';

export const postApplyMockHandler = [
http.post(`${getApply()}/:id`, async ({ request, params }) => {
http.post(`${APIPath.apply}`, async ({ request, params }) => {
const { id } = params;
const req = await request.json();
return HttpResponse.json({ req, id }, { status: 201 });
Expand Down
16 changes: 8 additions & 8 deletions src/apis/apply/useApplyHook.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { APIPath } from '@/apis/apiPath';
import { getDynamicAPIPath } from '@/apis/apiPath';
import { clientInstance } from '@/apis/instance';
import { useMutation } from '@tanstack/react-query';
// import { useNavigate } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';

export const getApply = () => `${APIPath.registerSign}`;
export const getApply = (recruitmentId: number) => `${getDynamicAPIPath.apply(recruitmentId)}`;

export const Apply = async ({ req, recruitmentId }: { req: string; recruitmentId: string }) => {
const response = await clientInstance.post(`${getApply()}/${recruitmentId}`, req);
export const Apply = async ({ req, recruitmentId }: { req: string; recruitmentId: number }) => {
const response = await clientInstance.post(`${getApply(recruitmentId)}`, req);
return response.data;
};

export const FetchApply = () => {
// const nav = useNavigate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 왜 대문자일까요... use가 붙어야하지 않을까요?

const nav = useNavigate();

return useMutation({
mutationFn: ({ data, recruitmentId }: { data: string; recruitmentId: string }) =>
mutationFn: ({ data, recruitmentId }: { data: string; recruitmentId: number }) =>
Apply({ req: data, recruitmentId }),
onSuccess: () => {
// nav('/');
nav('/');
},
});
};
30 changes: 30 additions & 0 deletions src/apis/auth/hooks/mutations/useGoogleOAuthMutation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { clientInstance } from '@apis/instance';
import { useMutation } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import { OAuthRequest } from '../../types/request';
import { OAuthResponse } from '../../types/response';
import { APIPath } from '@/apis/apiPath';

const postOAuth = async ({ code }: OAuthRequest): Promise<OAuthResponse> => {
const res = await clientInstance.post(APIPath.postOAuth, { code });

const authorizationHeader = res.headers['authorization'];
const accessToken = authorizationHeader.replace('Bearer ', '');

if (!accessToken) {
throw new Error('Authorization header is missing in the response');
}
Comment on lines +11 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헤더에 Bearer로 전달해주네요..? 서버에서 그렇게 해주는걸까요?


return {
accessToken,
type: res.data.type,
profileImage: res.data.profileImage,
name: res.data.name,
};
};

export function useGoogleOAuthMutation() {
return useMutation<OAuthResponse, AxiosError, OAuthRequest>({
mutationFn: postOAuth,
});
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { clientInstance } from '@apis/instance';
import { useMutation, UseMutationResult } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import { AUTH_PATH } from '../path';
import { RegisterRequest } from '../types/request';
import { RegisterResponse } from '../types/response';
import { RegisterRequest } from '../../types/request';
import { RegisterResponse } from '../../types/response';
import { APIPath } from '@/apis/apiPath';

const postRegister = async ({ type }: RegisterRequest): Promise<RegisterResponse> => {
const res = await clientInstance.post(AUTH_PATH.REGISTER, { type });
const res = await clientInstance.post(APIPath.postRegister, { type });
return res.data;
};

export const useRegister = (): UseMutationResult<RegisterResponse, AxiosError, RegisterRequest> => {
export const useRegisterMutation = (): UseMutationResult<RegisterResponse, AxiosError, RegisterRequest> => {
return useMutation<RegisterResponse, AxiosError, RegisterRequest>({
mutationFn: postRegister,
});
Expand Down
81 changes: 0 additions & 81 deletions src/apis/auth/mutations/useGoogleOAuth.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions src/apis/auth/path.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/apis/auth/types/request.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface OAuthRequest {
token: string;
code: string;
}

export interface RegisterRequest {
Expand Down
1 change: 1 addition & 0 deletions src/apis/auth/types/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface OAuthResponse {
accessToken: string;
type: 'first' | 'employee' | 'employer';
profileImage: string;
name: string;
}

export interface RegisterResponse {
Expand Down
2 changes: 1 addition & 1 deletion src/apis/companies/mocks/myCompaniesMockHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIPath } from '@/apis/apiPath';
import { companyList } from '@/pages/myPage/employer/EmployerMyPage.mock';
import { companyList } from './myCompanies.mock';
import { http, HttpResponse } from 'msw';

export const myCompaniesMockHandler = [http.get(APIPath.getMyCompanies, () => HttpResponse.json(companyList))];
15 changes: 15 additions & 0 deletions src/apis/contract/hooks/useGetContractImg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getDynamicAPIPath } from '@/apis/apiPath';
import { clientInstance } from '@/apis/instance';
import { useQuery } from '@tanstack/react-query';

export const getContractImgPath = (applyId: number) => `${getDynamicAPIPath.downloadContract(applyId)}`;
const getContractImg = async (applyId: number) => {
const res = await clientInstance.get(getContractImgPath(applyId));
return res.data;
};

export const useGetContractImg = (applyId: number) =>
useQuery({
queryKey: [getContractImgPath],
queryFn: () => getContractImg(applyId),
});
22 changes: 22 additions & 0 deletions src/apis/home/hooks/queries/useFetchRecruitments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { AxiosError } from 'axios';
import { RecruitmentResponse } from '../../types/response';
import { useSuspenseQuery, UseSuspenseQueryResult } from '@tanstack/react-query';
import { clientInstance } from '@apis/instance';
import { QUERY_KEYS } from './queryKeys';
import { getDynamicAPIPath } from '@/apis/apiPath';

const getRecruitments = async (filter: string, page: number): Promise<RecruitmentResponse[]> => {
const url = `${getDynamicAPIPath.getRecruitments(filter)}?page=${page}`;
const res = await clientInstance.get<RecruitmentResponse[]>(url);
return res.data;
};

export const useFetchRecruitments = (
filter: string,
page: number,
): UseSuspenseQueryResult<RecruitmentResponse[], AxiosError> => {
return useSuspenseQuery<RecruitmentResponse[], AxiosError>({
queryKey: [QUERY_KEYS.RECRUITMENTS, filter, page],
queryFn: () => getRecruitments(filter, page),
});
};
Loading
Loading