diff --git a/package-lock.json b/package-lock.json index 0131fd5..8eda480 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "hearus-react-frontend", "version": "0.0.0", + "license": "MIT", "dependencies": { "@tanstack/react-query": "^5.50.1", "react": "^18.3.1", diff --git a/src/apis/schedule.ts b/src/apis/schedule.ts index d2d7648..776fc89 100644 --- a/src/apis/schedule.ts +++ b/src/apis/schedule.ts @@ -13,26 +13,30 @@ interface IGetScheduleObject { export const getSchedule = async ( name: string, -): Promise => { + retryCount: number = 0, // 무한 루프 방지 +): Promise => { + const MAX_RETRIES = 1; const token = getToken(); - try { - const res = await fetch( - `${API_URL}/api/v1/schedule/getSchedule?name=${name}`, - { - headers: { - Authorization: `Bearer ${token}`, - }, + const res = await fetch( + `${API_URL}/api/v1/schedule/getSchedule?name=${name}`, + { + headers: { + Authorization: `Bearer ${token}`, }, - ); - const data: IGetScheduleResponse = await res.json(); - if (data.msg === 'Schedule not found with name') { - await createNewScheduleName(name); - return getSchedule(name); + }, + ); + const data: IGetScheduleResponse = await res.json(); + // userName으로 된 시간표가 없을 경우 만들고 재귀 호출 + if (data.msg === 'Schedule not found with name') { + if (retryCount >= MAX_RETRIES) { + throw new Error( + 'Maximum retry limit reached. Unable to create schedule.', + ); } - return data.object['scheduleElements']; - } catch (error) { - throw error; + await createNewScheduleName(name); + return getSchedule(name, retryCount + 1); } + return data; }; interface IGetLectureByScheduleElementResponse @@ -50,20 +54,16 @@ interface ILectureItem { export const getLectureByScheduleElement = async (id: number) => { const token = getToken(); - try { - const res = await fetch( - `${API_URL}/api/v1/lecture/getLectureByScheduleElement?scheduleElementId=${id}`, - { - headers: { - Authorization: `Bearer ${token}`, - }, + const res = await fetch( + `${API_URL}/api/v1/lecture/getLectureByScheduleElement?scheduleElementId=${id}`, + { + headers: { + Authorization: `Bearer ${token}`, }, - ); - const data: IGetLectureByScheduleElementResponse = await res.json(); - return data.object; - } catch (error) { - throw error; - } + }, + ); + const data: IGetLectureByScheduleElementResponse = await res.json(); + return data; }; interface IPOSTScheduleElementResponse extends IApiResponse {} @@ -73,25 +73,21 @@ export const addScheduleElement = async ( name: string, ) => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/schedule/addElement`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, + const res = await fetch(`${API_URL}/api/v1/schedule/addElement`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + scheduleDTO: { + name, }, - body: JSON.stringify({ - scheduleDTO: { - name, - }, - scheduleElementDTO: inputData, - }), - }); - const data: IPOSTScheduleElementResponse = await res.json(); - return data.success; - } catch (error) { - throw error; - } + scheduleElementDTO: inputData, + }), + }); + const data: IPOSTScheduleElementResponse = await res.json(); + return data; }; export const deleteScheduleElement = async ( @@ -99,29 +95,26 @@ export const deleteScheduleElement = async ( name: string, ) => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/schedule/deleteElement`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, + const res = await fetch(`${API_URL}/api/v1/schedule/deleteElement`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + scheduleDTO: { + name, }, - body: JSON.stringify({ - scheduleDTO: { - name, - }, - scheduleElementDTO: { - id: scheduleElementId, - }, - }), - }); - const data: IPOSTScheduleElementResponse = await res.json(); - return data.success; - } catch (error) { - throw error; - } + scheduleElementDTO: { + id: scheduleElementId, + }, + }), + }); + const data: IPOSTScheduleElementResponse = await res.json(); + return data; }; +/** 현재는 시간표 조회할때 userName으로 된 시간표 없을 때만 쓰임. */ const createNewScheduleName = async (name: string) => { const token = getToken(); try { diff --git a/src/apis/script.ts b/src/apis/script.ts index 0ffb7a3..19d98c7 100644 --- a/src/apis/script.ts +++ b/src/apis/script.ts @@ -20,35 +20,27 @@ interface IScriptDetail { processedScript: string[]; } -export const getAllScripts = async (): Promise => { +export const getAllScripts = async (): Promise => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/lecture/getAllLecture`, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - const data: IGetAllScriptResponse = await res.json(); - return data.object; - } catch (error) { - throw error; - } + const res = await fetch(`${API_URL}/api/v1/lecture/getAllLecture`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + const data: IGetAllScriptResponse = await res.json(); + return data; }; export const getScriptDetail = async (id: string) => { const token = getToken(); - try { - const res = await fetch( - `${API_URL}/api/v1/lecture/getLecture?lectureId=${id}`, - { - headers: { - Authorization: `Bearer ${token}`, - }, + const res = await fetch( + `${API_URL}/api/v1/lecture/getLecture?lectureId=${id}`, + { + headers: { + Authorization: `Bearer ${token}`, }, - ); - const data: IGetScriptDetailResponse = await res.json(); - return data.object; - } catch (error) { - throw error; - } + }, + ); + const data: IGetScriptDetailResponse = await res.json(); + return data; }; diff --git a/src/apis/test.ts b/src/apis/test.ts index 31fb3aa..28686d9 100644 --- a/src/apis/test.ts +++ b/src/apis/test.ts @@ -18,18 +18,14 @@ export interface IProblemInput { export const generateProblem = async (inputData: IProblemInput) => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/lecture/generateProblems`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - body: JSON.stringify(inputData), - }); - const data: IGenerateProblemResponse = await res.json(); - return data; - } catch (error) { - throw error; - } + const res = await fetch(`${API_URL}/api/v1/lecture/generateProblems`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify(inputData), + }); + const data: IGenerateProblemResponse = await res.json(); + return data; }; diff --git a/src/apis/user.ts b/src/apis/user.ts index 118e264..f25cb2e 100644 --- a/src/apis/user.ts +++ b/src/apis/user.ts @@ -37,17 +37,13 @@ export interface IUserSupplementaryUpdateInfo { export const getUserInfo = async () => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/user/present-user`, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - const data: IGetUserInfoResponse = await res.json(); - return data.object; - } catch (error) { - throw error; - } + const res = await fetch(`${API_URL}/api/v1/user/present-user`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + const data: IGetUserInfoResponse = await res.json(); + return data; }; export const updateInfo = async ({ @@ -58,50 +54,42 @@ export const updateInfo = async ({ userGrade, }: IUserUpdateInfo) => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/user/updateUser`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - body: JSON.stringify({ - userName, - userPassword, - userSchool, - userMajor, - userGrade, - }), - }); - const data: IUpdateUserInfoResponse = await res.json(); - return data.object; - } catch (error) { - throw error; - } + const res = await fetch(`${API_URL}/api/v1/user/updateUser`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + userName, + userPassword, + userSchool, + userMajor, + userGrade, + }), + }); + const data: IUpdateUserInfoResponse = await res.json(); + return data; }; -export const SupplementaryUpdateInfo = async ({ +export const updateSupplementaryInfo = async ({ userSchool, userMajor, userGrade, }: IUserSupplementaryUpdateInfo) => { const token = getToken(); - try { - const res = await fetch(`${API_URL}/api/v1/user/updateUser`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - body: JSON.stringify({ - userSchool, - userMajor, - userGrade, - }), - }); - const data: ISupplementaryUpdateInfoResponse = await res.json(); - return data.object; - } catch (error) { - throw error; - } + const res = await fetch(`${API_URL}/api/v1/user/updateUser`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + userSchool, + userMajor, + userGrade, + }), + }); + const data: ISupplementaryUpdateInfoResponse = await res.json(); + return data; }; diff --git a/src/assets/images/401image.png b/src/assets/images/401image.png new file mode 100644 index 0000000..500496c Binary files /dev/null and b/src/assets/images/401image.png differ diff --git a/src/components/atoms/HighlightedText/HighlightedText.tsx b/src/components/atoms/HighlightedText/HighlightedText.tsx index 6f153a3..56736fc 100644 --- a/src/components/atoms/HighlightedText/HighlightedText.tsx +++ b/src/components/atoms/HighlightedText/HighlightedText.tsx @@ -14,7 +14,11 @@ const HighlightedText = ({ text, isPreview }: IProps) => { if (index % 2 === 0) { return part; } else { - return {part}; + return ( + + {part} + + ); } })}

diff --git a/src/components/molecules/RecordTagDropDown/RecordTagDropDown.tsx b/src/components/molecules/RecordTagDropDown/RecordTagDropDown.tsx index b6666f7..9675a06 100644 --- a/src/components/molecules/RecordTagDropDown/RecordTagDropDown.tsx +++ b/src/components/molecules/RecordTagDropDown/RecordTagDropDown.tsx @@ -1,20 +1,22 @@ -import { useEffect, useMemo, useState } from 'react'; +import { useMemo, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import useRecordModalStore, { ITagItem, } from '../../../store/useRecordModalStore'; -import { IScheduleElement } from '../../../constants/schedule'; import { getSchedule } from '../../../apis/schedule'; -import styles from './RecordTagDropDown.module.scss'; import { useUserInfoStore } from '../../../store/useUserInfoStore'; +import { useUnauthorizedRedirect } from '../../../hooks/useUnauthorizedRedirect'; +import styles from './RecordTagDropDown.module.scss'; const RecordTagDropDown = () => { const { userInfo } = useUserInfoStore(); - const { data } = useQuery({ - queryKey: ['schedule', userInfo.userName], - queryFn: () => getSchedule(userInfo.userName), + const { data } = useQuery({ + queryKey: ['schedule', userInfo?.userName], + queryFn: () => getSchedule(userInfo?.userName), }); + useUnauthorizedRedirect(data); + const [isTagBtnClicked, setIsTagBtnClicked] = useState(false); const { recordData, updateRecordData } = useRecordModalStore(); @@ -25,7 +27,7 @@ const RecordTagDropDown = () => { const tagObject: { [key: string]: number } = {}; - data.forEach((item) => { + data?.object?.scheduleElements.forEach((item) => { if (!tagObject.hasOwnProperty(item.name)) { tagObject[item.name] = item.scheduleId; } @@ -46,14 +48,10 @@ const RecordTagDropDown = () => { setIsTagBtnClicked(false); }; - useEffect(() => { - console.log(recordData); - }, [recordData]); - return (
- {data?.map((lecture) => ( + {data?.object?.map((lecture) => (
{ const { userInfo } = useUserInfoStore(); - const firstLetter = userInfo.userName.charAt(0); + const firstLetter = userInfo?.userName.charAt(0); return (