From 0204ff0224162176c6d8faabc22b02c22b25a835 Mon Sep 17 00:00:00 2001 From: 6-keem <6ukeem@gmail.com> Date: Thu, 6 Feb 2025 19:34:37 +0900 Subject: [PATCH] feat: Add lecture evaluation retrieval feature --- .../components/CourseEvaluationModal.tsx | 107 +++++++++++------- src/hooks/fetchAPI.ts | 22 ++-- src/types/types.ts | 12 +- 3 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/content/subject/components/CourseEvaluationModal.tsx b/src/content/subject/components/CourseEvaluationModal.tsx index 0df4276..1eb6c51 100644 --- a/src/content/subject/components/CourseEvaluationModal.tsx +++ b/src/content/subject/components/CourseEvaluationModal.tsx @@ -1,7 +1,7 @@ import ReactDOM from 'react-dom'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { fetchCourseEvaluationData } from '@/hooks/fetchAPI'; -import { CourseEvaluation, Description } from '@/types/types'; +import { CourseEvaluation } from '@/types/types'; import { useEffect, useState, useContext } from 'react'; import { Button } from '@/components/ui/button'; import { ShadowRootContext } from '@/lib/ShadowRootContext'; @@ -12,9 +12,8 @@ interface ModalProp { } export function CourseEvaluationModal({ code, onClose }: ModalProp) { - const [courseEvaluation, setCourseEvaluation] = useState(null); + const [courseEvaluations, setCourseEvaluation] = useState([]); const shadowRoot = useContext(ShadowRootContext); - const [isVisible, setIsVisible] = useState(false); useEffect(() => { @@ -36,6 +35,14 @@ export function CourseEvaluationModal({ code, onClose }: ModalProp) { }, 300); }; + const groupedCourses: { [key: string]: CourseEvaluation[] } = {}; + courseEvaluations.forEach((evaluation) => { + if (!groupedCourses[evaluation.kyokwacode]) { + groupedCourses[evaluation.kyokwacode] = []; + } + groupedCourses[evaluation.kyokwacode].push(evaluation); + }); + const modalContent = (
e.stopPropagation()}> - {/* 닫기 버튼 */} - {courseEvaluation ? ( -
-

과목해설

- - - - 교과코드 - 과목명 - 교수 - 학년도 - 학기 - 점수 - - - - - {courseEvaluation.courseCode} - {courseEvaluation.courseName} - {courseEvaluation.professor} - {courseEvaluation.academicYear} - {courseEvaluation.semester} - {courseEvaluation.score} - - - 도움말 - - - -
    -
  • 해당 교과에 대한 교강사의 최근 2학기 강의평가 점수 조회 화면입니다.
  • -
  • 수강 신청 2주 전부터 정정일까지 확인 가능합니다.
  • -
-
-
-
-
-
- ) : ( -
로딩 중...
- )} +

과목해설

+ + + + 교과코드 + 과목명 + 교수 + 학년도 + 학기 + 점수 + + + + {courseEvaluations.length > 0 ? ( + Object.entries(groupedCourses).map(([key, evaluations]) => + evaluations.map((evaluation, index) => ( + + {index === 0 && ( + <> + {evaluation.kyokwacode} + {evaluation.kyokwaname} + {evaluation.kyosu} + + )} + {evaluation.hakneando} + {evaluation.hakgi} + {evaluation.jumsu} + + )) + ) + ) : ( + + + 데이터가 존재하지 않습니다. + + + )} + + 도움말 + + + +
    +
  • 해당 교과에 대한 교강사의 최근 2학기 강의평가 점수 조회 화면입니다.
  • +
  • 수강 신청 2주 전부터 정정일까지 확인 가능합니다.
  • +
+
+
+
+
); diff --git a/src/hooks/fetchAPI.ts b/src/hooks/fetchAPI.ts index ee6442b..97d30d5 100644 --- a/src/hooks/fetchAPI.ts +++ b/src/hooks/fetchAPI.ts @@ -289,7 +289,7 @@ export const fetchCourseEvaluationData = ({ setCourseEvaluation, }: { code: string; - setCourseEvaluation: (courseEvaluation: CourseEvaluation) => void; + setCourseEvaluation: (courseEvaluation: CourseEvaluation[]) => void; }) => { var xhr = new XMLHttpRequest(); xhr.open('POST', 'https://info.hansung.ac.kr/jsp_21/student/kyomu/siganpyo_aui_data.jsp', true); @@ -306,15 +306,17 @@ export const fetchCourseEvaluationData = ({ const parser = new xml2js.Parser(); const result: ParsedXML = await parser.parseStringPromise(xml); - // const item: any = result.root.items[0].item[0]; - const courseEvaluation: CourseEvaluation = { - academicYear: '2001', - courseCode: code, - courseName: '크롬익스텐션', - professor: '홍길동', - score: '4.5', - semester: '2학기', - }; + const items: any[] = result?.root?.items?.[0]?.item || []; + + const courseEvaluation: CourseEvaluation[] = items.map((item) => ({ + kyokwacode: item.kyokwacode?.[0] || '', + kyokwaname: item.kyokwaname?.[0] || '', + kyosu: item.kyosu?.[0] || '', + hakgi: item.hakgi?.[0] || '', + hakneando: item.hakneando?.[0] || '', + jumsu: item.jumsu?.[0] || '', + })); + setCourseEvaluation(courseEvaluation); } catch (err) { console.error('XML parsing failed:', err); diff --git a/src/types/types.ts b/src/types/types.ts index 30372ff..5850ad5 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -111,12 +111,12 @@ export interface Description { } export interface CourseEvaluation { - courseCode: string; - courseName: string; - professor: string; - academicYear: string; - semester: string; - score: string; + kyokwacode: string; + kyokwaname: string; + kyosu: string; + hakneando: string; + hakgi: string; + jumsu: string; } /**