-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat(time): 타임테이블 모달 api 연동 #211
Changes from 11 commits
3b3cb40
59104f3
bccc52f
7ef2e26
b216950
a7f3a80
ed7bf6f
3743ce0
c6141e5
0fc8218
e5a44ac
5474564
51b6f3e
944877d
3e670eb
8c3fd38
23ea19d
290fb41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useEffect, useState } from 'react'; | ||
|
||
interface UseDebounceParams { | ||
value: unknown; | ||
delay: number; | ||
} | ||
|
||
export default function useDebounce({ value, delay }: UseDebounceParams) { | ||
const [debouncedValue, setDebouncedValue] = useState<unknown>(value); | ||
|
||
useEffect(() => { | ||
const delayDebounceTimer = setTimeout(() => { | ||
setDebouncedValue(value); | ||
}, delay); | ||
return () => clearTimeout(delayDebounceTimer); | ||
}, [value, delay]); | ||
|
||
return debouncedValue; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const TIMETABLE_ENDPOINT = { | ||
getLectureList: 'api/v1/lecture/retrieve', | ||
getMajorList: 'api/v1/lecture/retrieve/major', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. get 요청 말고 다른 경우에도 동일한 엔드포인트를 사용해야 할 수도 있기 때문에 접두사를 빼고 LecturList로만 작성해도 괜찮을 것 같아요. 환경변수 설정 시에 또, 엔드포인트 값은 변경되지 않을 상수이므로 TIMETABLE_ENDPOINT처럼 전체 대문자로 아름을 설정해도 좋을 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저는 개인적으로 앞에 아래 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저는 코드 내에 작성 됐을 때 모두 대문자 스네이크 케이스인게 좀 더 직관적으로 선언문 내부의 속성이 상수라는 사실을 알 수 있다고 생각해서 모두 대문자 스네이크 케이스로 사용하고 있어요. 처음 코드를 보는 사람이 봤을 때도 바로 상수라는 사실을 알아차릴 수 있을 것이라고 생각해요. 이번에 의견을 나눠보고 한 방법으로 통일시키면 어떨까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
말씀하신대로 객체 내부 값은 변경될 수 있어요, 하지만 이와 같이 Endpoint를 나타내는 상수 값은
TIMETABLE_ENDPOINT 객체의 요소(값)들은 과연 상수일까요? 내부 값도 const NEW_TIMETABLE_ENDPOINT = {
GET_LECTURELIST: 'api/v1/lecture/retrieve', // is readonly
GET_MAJORLIST: 'api/v1/lecture/retrieve/major' // is readonly
} as const |
||
}; | ||
|
||
export default TIMETABLE_ENDPOINT; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { DayKor } from '@/shared/types'; | ||
import type { | ||
DayCampus, | ||
DayPeriod, | ||
Grade, | ||
LectureKey, | ||
NightCampus, | ||
NightPeriod, | ||
} from '@/widgets/time-table'; | ||
import { TIMETABLE_ENDPOINT } from '@/widgets/time-table'; | ||
|
||
export interface GetLectureListParams { | ||
campus: (DayCampus | NightCampus)[]; | ||
type: LectureKey[]; | ||
grade: Grade[]; | ||
day: DayKor[]; | ||
time: (DayPeriod | NightPeriod)[]; | ||
major: string[]; | ||
lectureName: string; | ||
cursor: number; | ||
limit: number; | ||
} | ||
|
||
export interface GetLectureListResponseValue { | ||
id: number; | ||
campus: string; | ||
category: string; | ||
code: string; | ||
credit: number; | ||
grade: number; | ||
groupName: string; | ||
isExceeded: true; | ||
major: string; | ||
name: string; | ||
professor: string; | ||
room: string; | ||
year: number; | ||
semester: string; | ||
time: string; | ||
type: LectureKey; | ||
} | ||
|
||
export interface GetLectureListResponse { | ||
success: boolean; | ||
data: { | ||
values: GetLectureListResponseValue[]; | ||
}; | ||
hasPrevious: boolean; | ||
hasNext: boolean; | ||
} | ||
|
||
export async function getLectureList({ | ||
...params | ||
}: GetLectureListParams): Promise<GetLectureListResponse> { | ||
const apiURL = new URL( | ||
`${process.env.NEXT_PUBLIC_SERVER_URL}/${TIMETABLE_ENDPOINT.getLectureList}`, | ||
); | ||
Jeong-Ag marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Object.entries(params).forEach(([key, value]) => { | ||
if (value) { | ||
apiURL.searchParams.set( | ||
key, | ||
Array.isArray(value) ? value.join(',') : String(value), | ||
); | ||
} | ||
}); | ||
|
||
const res = await fetch(apiURL); | ||
|
||
if (!res.ok) { | ||
throw new Error('강의 정보 불러오기에 실패했습니다.'); | ||
} | ||
|
||
return res.json(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { TIMETABLE_ENDPOINT } from '@/widgets/time-table'; | ||
|
||
export interface GetMajorListParams { | ||
major: string; | ||
} | ||
|
||
export interface GetMajorListResponse { | ||
success: boolean; | ||
data: string[]; | ||
} | ||
|
||
export async function getMajorList({ | ||
major, | ||
}: GetMajorListParams): Promise<GetMajorListResponse> { | ||
const apiURL = new URL( | ||
`${process.env.NEXT_PUBLIC_SERVER_URL}/${TIMETABLE_ENDPOINT.getMajorList}`, | ||
); | ||
|
||
apiURL.searchParams.set('major', major); | ||
|
||
const res = await fetch(apiURL); | ||
|
||
if (!res.ok) { | ||
throw new Error('전공 리스트 불러오기에 실패했습니다.'); | ||
} | ||
|
||
return res.json(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { default as TIMETABLE_ENDPOINT } from './endpoint'; | ||
export * from './getLectureList'; | ||
export * from './getMajorList'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './ui'; | ||
export * from './model'; | ||
export * from './types'; | ||
export * from './api'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
export { default as timeTableQueryKeys } from './timeTableQueryKeys'; | ||
export { default as useTimeTableParams } from './useTimeTableParams'; | ||
export { default as useMajorList } from './useMajorList'; | ||
export { default as useLectureList } from './useLectureList'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { GetLectureListParams, GetMajorListParams } from '@/widgets/time-table'; | ||
|
||
const timeTableQueryKeys = { | ||
getLectureList: (params: GetLectureListParams) => ['getLectureList', params], | ||
getMajorList: (params: GetMajorListParams) => ['getMajorList', params], | ||
}; | ||
|
||
export default timeTableQueryKeys; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { useSuspenseQuery } from '@tanstack/react-query'; | ||
|
||
import { | ||
type GetLectureListParams, | ||
getLectureList, | ||
timeTableQueryKeys, | ||
} from '@/widgets/time-table'; | ||
|
||
export default function useLectureList({ ...params }: GetLectureListParams) { | ||
return useSuspenseQuery({ | ||
queryKey: timeTableQueryKeys.getLectureList(params), | ||
queryFn: () => getLectureList(params), | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useQuery } from '@tanstack/react-query'; | ||
|
||
import { | ||
type GetMajorListParams, | ||
getMajorList, | ||
timeTableQueryKeys, | ||
} from '@/widgets/time-table'; | ||
|
||
export default function useMajorList({ major }: GetMajorListParams) { | ||
const { data } = useQuery({ | ||
queryKey: timeTableQueryKeys.getMajorList({ major }), | ||
queryFn: () => getMajorList({ major }), | ||
enabled: major.length > 0, | ||
}); | ||
|
||
return data ? data.data : []; | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
export * from './day-status'; | ||
export * from './grade'; | ||
export * from './period'; | ||
export * from './lecture'; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
import { REGION } from '@/widgets/time-table'; | ||
import { CAMPUS_STATUS, DAY_STATUS, REGION } from '@/widgets/time-table'; | ||
|
||
export type Region = (typeof REGION)[keyof typeof REGION]; | ||
|
||
export type DayStatus = keyof typeof DAY_STATUS; | ||
|
||
export type DayCampus = (typeof CAMPUS_STATUS.day)[number]; | ||
|
||
export type NightCampus = (typeof CAMPUS_STATUS.night)[number]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
기존 코드의 리턴 값과
value
의 타입은unkown
이에요, 제너릭을 활용하여 적절한 타입이 추론되도록 유도해보는 건 어떨까요?? (타입스크립트의 타입성이 보장되지 않기 때문)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋은 생각이네요! 제네릭을 적용하여 재설계해볼게요