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] feat#233#210 API 분리 및 함수 구현 & 서비스 전체 예외상황 리스트 체크 #234

Merged
merged 10 commits into from
Nov 21, 2024
91 changes: 91 additions & 0 deletions FE/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion FE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@emotion/styled": "^11.13.0",
"@mui/material": "^6.1.6",
"@tanstack/react-query": "^5.59.19",
"axios": "^1.7.7",
Copy link
Collaborator

Choose a reason for hiding this comment

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

fetch가 아닌 axios를 선택한 이유가 있을까요? (궁금)

"framer-motion": "^11.11.11",
"lottie-react": "^2.4.0",
"lottie-web": "^5.12.2",
Expand Down Expand Up @@ -49,4 +50,4 @@
"public"
]
}
}
}
52 changes: 52 additions & 0 deletions FE/src/api/rest/authApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import axios from 'axios';
import axiosInstance from './instance';

type LoginResponse = {
result: string;
Copy link

Choose a reason for hiding this comment

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

result는 좀더 구체적인 이름으로. string말고 더 구체적인 형태도 될 듯? 보통 응답은 객체로 하면 객체타입으로 표현해도 되고요.

};

export async function login(email: string, password: string): Promise<LoginResponse | null> {
try {
const payload = { email, password };

const response = await axiosInstance.post<LoginResponse>('/api/auth/login', payload);

console.log('Login Successful:', response.data);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Login Error:', error.response?.data || error.message);
} else {
console.error('Unexpected Error:', error);
Copy link

Choose a reason for hiding this comment

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

에러처리의 목적인 개발자에게 보여줄것인가? 사용자에게 다음행동을 유도할것인가? 를 생각해서 처리하면더 좋을듯요.

}

return null;
}
}

type SignupPayload = {
email: string;
password: string;
nickname: string;
};

type SignupResponse = {
result: string;
};

export async function signUp(data: SignupPayload): Promise<SignupResponse | null> {
try {
const response = await axiosInstance.post<SignupResponse>('/api/auth/signup', data);
console.log('Signup Successful:', response.data);

return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Signup Error:', error.response?.data || error.message);
} else {
console.error('Unexpected Error:', error);
}
Comment on lines +44 to +48
Copy link

Choose a reason for hiding this comment

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

이부분이 login과 비슷하게 할거면 통합해서 함수로 만들어도 될 듯.


return null;
}
}
53 changes: 53 additions & 0 deletions FE/src/api/rest/instance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import axios from 'axios';

const BASE_URL = 'test';

const axiosInstance = axios.create({
baseURL: BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});

axiosInstance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);

// axiosInstance.interceptors.response.use(
// (response) => {
// if (response.status === 404) {
// console.log('404 페이지로 이동');
// }

// return response;
// },
// async (error) => {
// if (error.response?.status === 401) {
// // isTokenExpired() - 토큰 만료 여부를 확인하는 함수
// // tokenRefresh() - 토큰을 갱신해주는 함수
// if (isTokenExpired()) await tokenRefresh();

// const accessToken = getToken();

// error.config.headers = {
// 'Content-Type': 'application/json',
// Authorization: `Bearer ${accessToken}`
// };

// // 중단된 요청을(에러난 요청)을 토큰 갱신 후 재요청
// const response = await axios.request(error.config);
// return response;
// }
// return Promise.reject(error);
// }
// );

export default axiosInstance;
82 changes: 82 additions & 0 deletions FE/src/api/rest/quizApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import axiosInstance from './instance';
import {
CreateQuizSetPayload,
CreateQuizSetResponse,
QuizSet,
QuizSetDetailResponse,
QuizSetListResponse
} from './quizTypes';

// 퀴즈셋 목록 조회 (검색, 페이징 고려)
export async function getQuizSetList(
category: string,
cursor: string,
take: number,
search: string
): Promise<QuizSetListResponse | null> {
try {
const params = { category, cursor, take, search };
const response = await axiosInstance.get<QuizSetListResponse>('/api/quizset', { params });

return response.data;
} catch (error) {
console.error('Error fetching quiz set list:', error);
return null;
}
}

// 퀴즈셋 하나 조회
export async function getQuizSetDetail(id: string): Promise<QuizSetDetailResponse | null> {
try {
const response = await axiosInstance.get<QuizSetDetailResponse>(`/api/quizset/${id}`);
return response.data;
} catch (error) {
console.error('Error fetching quiz set detail:', error);
return null;
}
}
// 제작한 퀴즈셋 목록 조회 (로그인 된 사용자)
export async function getMyQuizSets(): Promise<QuizSet[] | null> {
try {
const response = await axiosInstance.get<QuizSet[]>('/api/quizset/private');
return response.data;
} catch (error) {
console.error('Error fetching private quiz sets:', error);
return null;
}
}

// 퀴즈셋 생성
export async function createQuizSet(
data: CreateQuizSetPayload
): Promise<CreateQuizSetResponse | null> {
try {
const response = await axiosInstance.post<CreateQuizSetResponse>('/api/quizset', data);
return response.data;
} catch (error) {
console.error('Error creating quiz set:', error);
return null;
}
}
// 퀴즈셋 수정
export async function updateQuizSet(
id: string,
data: CreateQuizSetPayload
): Promise<CreateQuizSetResponse | null> {
try {
const response = await axiosInstance.patch<CreateQuizSetResponse>(`/api/quizset/${id}`, data);
return response.data;
} catch (error) {
console.error('Error updating quiz set:', error);
return null;
}
}
// 퀴즈셋 삭제
export async function deleteQuizSet(id: string): Promise<void> {
try {
await axiosInstance.delete(`/api/quizset/${id}`);
console.log(`Quiz set ${id} deleted successfully`);
} catch (error) {
console.error('Error deleting quiz set:', error);
}
}
Loading