1
- import React , { useEffect , useState } from 'react' ;
2
- import { Table , TableBody , TableCell , TableContainer , TableHead , TableRow , Paper , Typography , Box , IconButton , Collapse , CircularProgress , useMediaQuery , useTheme } from '@mui/material' ;
3
- import { Visibility , VisibilityOff } from '@mui/icons-material' ;
4
- import api from '../../../utils/api' ;
1
+ import React , { useEffect , useState } from "react" ;
2
+ import {
3
+ Table ,
4
+ TableBody ,
5
+ TableCell ,
6
+ TableContainer ,
7
+ TableHead ,
8
+ TableRow ,
9
+ Paper ,
10
+ Typography ,
11
+ Box ,
12
+ IconButton ,
13
+ Collapse ,
14
+ CircularProgress ,
15
+ useMediaQuery ,
16
+ useTheme ,
17
+ } from "@mui/material" ;
18
+ import { Visibility , VisibilityOff } from "@mui/icons-material" ;
19
+ import api from "../../../utils/api" ;
5
20
6
21
// interface QuizResult {
7
22
// _id: string;
@@ -55,7 +70,7 @@ const QuizResults: React.FC<QuizResultsProps> = ({
55
70
selectedSubject,
56
71
handleQuizResultClick,
57
72
handleCloseDetails,
58
- isStudentView = false , // 기본값은 false로 설정
73
+ isStudentView = false , // 기본값은 false로 설정
59
74
} ) => {
60
75
const [ quizResults , setQuizResults ] = useState < QuizResult [ ] > ( [ ] ) ;
61
76
const [ loading , setLoading ] = useState < boolean > ( false ) ;
@@ -65,27 +80,27 @@ const QuizResults: React.FC<QuizResultsProps> = ({
65
80
const [ quizDetails , setQuizDetails ] = useState < QuizDetail [ ] > ( [ ] ) ;
66
81
67
82
const theme = useTheme ( ) ;
68
- const isMobile = useMediaQuery ( theme . breakpoints . down ( 'sm' ) ) ;
83
+ const isMobile = useMediaQuery ( theme . breakpoints . down ( "sm" ) ) ;
69
84
70
85
// 학생일 경우 점수를 평가 문구 및 이모티콘으로 변환하는 함수
71
86
const getEvaluation = ( score : number ) => {
72
87
if ( score >= 75 ) {
73
- return { text : ' 훌륭해요' , emoji : '🏆' } ;
88
+ return { text : " 훌륭해요" , emoji : "🏆" } ;
74
89
} else if ( score >= 55 ) {
75
- return { text : ' 잘했어요' , emoji : '👍' } ;
90
+ return { text : " 잘했어요" , emoji : "👍" } ;
76
91
} else {
77
- return { text : ' 노력해요' , emoji : '💪' } ;
92
+ return { text : " 노력해요" , emoji : "💪" } ;
78
93
}
79
94
} ;
80
95
81
96
// 교사일 경우 단원별 총평을 상/중/하로 변환하는 함수
82
97
const getTeacherUnitEvaluation = ( score : number ) => {
83
98
if ( score >= 75 ) {
84
- return ' 상 🟢' ;
99
+ return " 상 🟢" ;
85
100
} else if ( score >= 55 ) {
86
- return ' 중 🟡' ;
101
+ return " 중 🟡" ;
87
102
} else {
88
- return ' 하 🔴' ;
103
+ return " 하 🔴" ;
89
104
}
90
105
} ;
91
106
@@ -100,8 +115,8 @@ const QuizResults: React.FC<QuizResultsProps> = ({
100
115
setQuizResults ( response . data ) ;
101
116
setNoData ( response . data . length === 0 ) ;
102
117
} catch ( err ) {
103
- console . error ( ' API 호출 실패:' , err ) ;
104
- setError ( ' 퀴즈 결과를 가져오는 중 오류가 발생했습니다.' ) ;
118
+ console . error ( " API 호출 실패:" , err ) ;
119
+ setError ( " 퀴즈 결과를 가져오는 중 오류가 발생했습니다." ) ;
105
120
setNoData ( true ) ;
106
121
} finally {
107
122
setLoading ( false ) ;
@@ -114,12 +129,15 @@ const QuizResults: React.FC<QuizResultsProps> = ({
114
129
115
130
const results = studentId ? quizResults : filteredResults || [ ] ;
116
131
117
- const filteredQuizResults = ( selectedSemester && selectedSubject )
118
- ? results . filter ( result =>
119
- ( selectedSemester === 'All' || result . semester === selectedSemester ) &&
120
- ( selectedSubject === 'All' || result . subject === selectedSubject )
121
- )
122
- : results ;
132
+ const filteredQuizResults =
133
+ selectedSemester && selectedSubject
134
+ ? results . filter (
135
+ ( result ) =>
136
+ ( selectedSemester === "All" ||
137
+ result . semester === selectedSemester ) &&
138
+ ( selectedSubject === "All" || result . subject === selectedSubject )
139
+ )
140
+ : results ;
123
141
124
142
if ( studentId && loading ) {
125
143
return < CircularProgress /> ;
@@ -131,15 +149,17 @@ const QuizResults: React.FC<QuizResultsProps> = ({
131
149
132
150
const fetchQuizDetails = async ( quizId : string ) => {
133
151
try {
134
- const response = await api . get ( `/quiz-results/details/${ quizId } /${ studentId } ` ) ;
152
+ const response = await api . get (
153
+ `/quiz-results/details/${ quizId } /${ studentId } `
154
+ ) ;
135
155
setQuizDetails ( response . data ) ;
136
156
} catch ( err ) {
137
- console . error ( ' Failed to fetch quiz details:' , err ) ;
157
+ console . error ( " Failed to fetch quiz details:" , err ) ;
138
158
}
139
159
} ;
140
160
141
161
// const toggleQuizDetails = (quizId: string) => {
142
- // setExpandedQuizId(prev => (prev === quizId ? null : quizId));
162
+ // setExpandedQuizId(prev => (prev === quizId ? null : quizId));
143
163
// };
144
164
145
165
const toggleQuizDetails = ( quizId : string ) => {
@@ -159,7 +179,9 @@ const QuizResults: React.FC<QuizResultsProps> = ({
159
179
</ Box >
160
180
) : filteredQuizResults . length === 0 ? (
161
181
< Box textAlign = "center" sx = { { mt : 2 } } >
162
- < Typography > 선택한 학기 또는 과목에 대한 퀴즈 내역이 없습니다.</ Typography >
182
+ < Typography >
183
+ 선택한 학기 또는 과목에 대한 퀴즈 내역이 없습니다.
184
+ </ Typography >
163
185
</ Box >
164
186
) : (
165
187
< TableContainer component = { Paper } sx = { { mt : 2 } } >
@@ -170,63 +192,91 @@ const QuizResults: React.FC<QuizResultsProps> = ({
170
192
{ ! isMobile && < TableCell > 학기</ TableCell > }
171
193
< TableCell > 과목</ TableCell >
172
194
{ ! isMobile && < TableCell > 단원</ TableCell > }
173
- < TableCell > 총평 </ TableCell >
195
+ < TableCell > 점수 </ TableCell >
174
196
< TableCell align = "center" > 상세보기</ TableCell >
175
197
</ TableRow >
176
198
</ TableHead >
177
199
< TableBody >
178
- { filteredQuizResults . map ( result => (
200
+ { filteredQuizResults . map ( ( result ) => (
179
201
< React . Fragment key = { result . _id } >
180
- < TableRow sx = { { cursor : 'pointer' } } >
181
- < TableCell > { new Date ( result . createdAt ) . toLocaleDateString ( ) } </ TableCell >
202
+ < TableRow sx = { { cursor : "pointer" } } >
203
+ < TableCell >
204
+ { new Date ( result . createdAt ) . toLocaleDateString ( ) }
205
+ </ TableCell >
182
206
{ ! isMobile && < TableCell > { result . semester } </ TableCell > }
183
207
< TableCell > { result . subject } </ TableCell >
184
208
{ ! isMobile && < TableCell > { result . unit } </ TableCell > }
185
-
186
- < TableCell >
187
- { isStudentView
188
- ? `${ getEvaluation ( result . score ) . text } ${ getEvaluation ( result . score ) . emoji } `
189
- : getTeacherUnitEvaluation ( result . score ) }
190
- </ TableCell >
209
+
210
+ < TableCell > { Math . round ( result . score ) } </ TableCell >
191
211
192
212
< TableCell align = "center" >
193
- < IconButton
213
+ < IconButton
194
214
onClick = { ( ) => toggleQuizDetails ( result . quizId ) }
195
215
color = "primary"
196
216
aria-label = "view details"
197
217
>
198
- { expandedQuizId === result . quizId ? < VisibilityOff /> : < Visibility /> }
218
+ { expandedQuizId === result . quizId ? (
219
+ < VisibilityOff />
220
+ ) : (
221
+ < Visibility />
222
+ ) }
199
223
</ IconButton >
200
224
</ TableCell >
201
225
</ TableRow >
202
226
< TableRow >
203
- < TableCell colSpan = { isMobile ? 5 : 6 } sx = { { padding : 0 , borderBottom : 'none' } } >
204
- < Collapse in = { expandedQuizId === result . quizId } timeout = "auto" unmountOnExit >
227
+ < TableCell
228
+ colSpan = { isMobile ? 5 : 6 }
229
+ sx = { { padding : 0 , borderBottom : "none" } }
230
+ >
231
+ < Collapse
232
+ in = { expandedQuizId === result . quizId }
233
+ timeout = "auto"
234
+ unmountOnExit
235
+ >
205
236
< Box sx = { { padding : 2 } } >
206
237
< Typography variant = "h6" gutterBottom >
207
238
퀴즈 상세 내용
208
239
</ Typography >
209
- < Typography variant = "body1" > 과목: { result . subject } </ Typography >
210
- < Typography variant = "body1" > 단원: { result . unit } </ Typography >
211
- < Typography variant = "body1" > 총평: { isStudentView ? `${ getEvaluation ( result . score ) . text } ${ getEvaluation ( result . score ) . emoji } ` : getTeacherUnitEvaluation ( result . score ) } </ Typography >
212
-
240
+ < Typography variant = "body1" >
241
+ 과목: { result . subject }
242
+ </ Typography >
243
+ < Typography variant = "body1" >
244
+ 단원: { result . unit }
245
+ </ Typography >
246
+ < Typography variant = "body1" >
247
+ 점수: { Math . round ( result . score ) }
248
+ </ Typography >
249
+
213
250
< TableContainer component = { Paper } sx = { { mt : 2 } } >
214
251
< Table >
215
252
< TableHead >
216
253
< TableRow >
217
254
< TableCell > 문제</ TableCell >
218
255
< TableCell > 정답</ TableCell >
219
256
< TableCell > 내 답변</ TableCell >
220
- { ! isStudentView && < TableCell > 정답 여부</ TableCell > }
257
+ { ! isStudentView && (
258
+ < TableCell > 정답 여부</ TableCell >
259
+ ) }
221
260
</ TableRow >
222
261
</ TableHead >
223
262
< TableBody >
224
263
{ quizDetails . map ( ( detail , index ) => (
225
264
< TableRow key = { index } >
226
- < TableCell > { detail . questionText || '문제를 찾을 수 없음' } </ TableCell >
227
- < TableCell > { detail . correctAnswer } </ TableCell >
228
- < TableCell > { detail . studentAnswer } </ TableCell >
229
- { ! isStudentView && < TableCell > { detail . isCorrect ? '정답' : '오답' } </ TableCell > }
265
+ < TableCell >
266
+ { detail . questionText ||
267
+ "문제를 찾을 수 없음" }
268
+ </ TableCell >
269
+ < TableCell >
270
+ { detail . correctAnswer }
271
+ </ TableCell >
272
+ < TableCell >
273
+ { detail . studentAnswer }
274
+ </ TableCell >
275
+ { ! isStudentView && (
276
+ < TableCell >
277
+ { detail . isCorrect ? "정답" : "오답" }
278
+ </ TableCell >
279
+ ) }
230
280
</ TableRow >
231
281
) ) }
232
282
</ TableBody >
0 commit comments