@@ -218,8 +218,9 @@ const TodayQuizSection: React.FC = () => {
218218 return ;
219219 }
220220
221- // 주관식인 경우 답안 확인
222- if ( displayQuiz ?. quizType === 'SUBJECTIVE' && subjectiveAnswer . trim ( ) === '' ) {
221+ // 서술형인 경우 답안 확인 FIXME: 주관식은 일단 제외)
222+ // if ((displayQuiz?.quizType === 'SHORT_ANSWER' || displayQuiz?.quizType === 'SUBJECTIVE') && subjectiveAnswer.trim() === '') {
223+ if ( ( displayQuiz ?. quizType === 'SHORT_ANSWER' || displayQuiz ?. quizType === 'SUBJECTIVE' ) && subjectiveAnswer . trim ( ) === '' ) {
223224 openModal ( {
224225 title : '답안 입력 필요' ,
225226 content : (
@@ -290,17 +291,43 @@ const TodayQuizSection: React.FC = () => {
290291
291292 setAnswerResult ( result ) ;
292293 setIsSubmitted ( true ) ;
293- } else if ( displayQuiz . quizType === 'SUBJECTIVE' ) {
294- // 주관식: AI 피드백 없음, 단순 결과 표시
295- const result : AnswerResult = {
296- isCorrect : true , // 주관식은 정답/오답 구분 없음
297- answer : displayQuiz . answer || '' ,
298- commentary : displayQuiz . commentary
299- } ;
300-
301- setAnswerResult ( result ) ;
294+ } else if ( displayQuiz . quizType === 'SHORT_ANSWER' ) {
295+ // 주관식: 평가 API 호출하여 정답/오답 확인
302296 setIsSubmitted ( true ) ;
303- } else if ( displayQuiz . quizType === 'ESSAY' ) {
297+
298+ try {
299+ // 평가 API 호출하여 정답/오답 결과 받기
300+ const evaluateResponse = await quizAPI . evaluateQuizAnswer ( userQuizAnswerId ) ;
301+
302+ // 평가 응답에서 결과 추출
303+ let evaluateData ;
304+ if ( evaluateResponse && typeof evaluateResponse === 'object' ) {
305+ evaluateData = ( 'data' in evaluateResponse ) ? evaluateResponse . data : evaluateResponse ;
306+ } else {
307+ evaluateData = evaluateResponse ;
308+ }
309+
310+ // 평가 결과로 결과 설정
311+ const result : AnswerResult = {
312+ isCorrect : ( evaluateData as any ) ?. isCorrect || false ,
313+ answer : ( evaluateData as any ) ?. answer || displayQuiz . answer || '' ,
314+ commentary : ( evaluateData as any ) ?. commentary || displayQuiz . commentary
315+ } ;
316+
317+ setAnswerResult ( result ) ;
318+ } catch ( evaluateError ) {
319+ console . error ( '주관식 답안 평가 실패:' , evaluateError ) ;
320+
321+ // 평가 API 실패 시 기본값으로 처리
322+ const fallbackResult : AnswerResult = {
323+ isCorrect : false ,
324+ answer : displayQuiz . answer || '' ,
325+ commentary : displayQuiz . commentary
326+ } ;
327+
328+ setAnswerResult ( fallbackResult ) ;
329+ }
330+ } else if ( displayQuiz . quizType === 'SUBJECTIVE' ) {
304331 // 서술형: AI 피드백 있음
305332 // 먼저 기본 결과 표시 (AI 피드백 없이)
306333 const initialResult : AnswerResult = {
@@ -314,7 +341,6 @@ const TodayQuizSection: React.FC = () => {
314341 setIsAiFeedbackLoading ( true ) ;
315342 setStreamingFeedback ( 'AI 응답 대기 중...' ) ;
316343
317- // userQuizAnswerId는 이미 위에서 추출했으므로 그대로 사용
318344
319345 try {
320346 // SSE를 통한 AI 피드백 스트리밍
@@ -333,9 +359,9 @@ const TodayQuizSection: React.FC = () => {
333359 }
334360
335361 const sseConnection = quizAPI . streamAiFeedback (
336- userQuizAnswerId ,
337- // onData: 스트리밍 데이터 수신
338- ( data : string ) => {
362+ userQuizAnswerId ,
363+ // onData: 스트리밍 데이터 수신
364+ ( data : string ) => {
339365 // 받은 데이터 로깅 (디버깅용)
340366 console . log ( '받은 SSE 데이터:' , JSON . stringify ( data ) ) ;
341367
@@ -465,7 +491,7 @@ const TodayQuizSection: React.FC = () => {
465491 const cleanAnswerText = choiceText ? choiceText . replace ( / ^ \d + \. \s * / , '' ) : '' ;
466492 answerText = `${ correctAnswerNumber } 번. ${ cleanAnswerText } ` ;
467493 } else {
468- // 주관식의 경우
494+ // 주관식/단답형의 경우
469495 isCorrect = subjectiveAnswer . trim ( ) . toLowerCase ( ) === ( displayQuiz . answer || '' ) . toLowerCase ( ) ;
470496 answerText = displayQuiz . answer || '' ;
471497 }
@@ -649,6 +675,30 @@ const TodayQuizSection: React.FC = () => {
649675 ) }
650676
651677 { /* 주관식 문제 */ }
678+ { displayQuiz ?. quizType === 'SHORT_ANSWER' && (
679+ < div className = "max-w-4xl mx-auto mb-8" >
680+ < div className = "bg-white rounded-xl sm:rounded-2xl border-2 border-gray-200 p-4 sm:p-6" >
681+ < label htmlFor = "short-answer" className = "block text-base sm:text-lg font-medium text-gray-900 mb-4" >
682+ 답안을 입력해주세요
683+ </ label >
684+ < input
685+ type = "text"
686+ id = "short-answer"
687+ value = { subjectiveAnswer }
688+ onChange = { ( e ) => setSubjectiveAnswer ( e . target . value ) }
689+ disabled = { isSubmitted }
690+ className = { `w-full p-3 sm:p-4 border-2 rounded-lg sm:rounded-xl text-base sm:text-lg leading-relaxed transition-all duration-300 ${
691+ isSubmitted
692+ ? 'border-gray-200 bg-gray-50 text-gray-600 cursor-not-allowed'
693+ : 'border-gray-300 focus:border-brand-500 focus:ring-4 focus:ring-brand-100 focus:outline-none'
694+ } `}
695+ placeholder = "짧은 답안을 입력하세요..."
696+ />
697+ </ div >
698+ </ div >
699+ ) }
700+
701+ { /* 서술형 문제 */ }
652702 { displayQuiz ?. quizType === 'SUBJECTIVE' && (
653703 < div className = "max-w-4xl mx-auto mb-8" >
654704 < div className = "bg-white rounded-xl sm:rounded-2xl border-2 border-gray-200 p-4 sm:p-6" >
@@ -675,8 +725,8 @@ const TodayQuizSection: React.FC = () => {
675725 { /* Result Section - 제출 후에만 표시 */ }
676726 { isSubmitted && answerResult && (
677727 < div className = "max-w-4xl mx-auto mb-8" >
678- { /* 정답/오답 메시지 - 객관식에만 표시 */ }
679- { displayQuiz ?. quizType === 'MULTIPLE_CHOICE' && (
728+ { /* 정답/오답 메시지 - 객관식, 주관식에 표시 FIXME: 주관식은 일단 제외) */ }
729+ { ( displayQuiz ?. quizType === 'MULTIPLE_CHOICE' ) && (
680730 < div className = { `inline-flex items-center rounded-full px-6 py-3 mb-6 ${
681731 answerResult . isCorrect ? 'bg-green-100' : 'bg-red-100'
682732 } `} >
@@ -701,8 +751,8 @@ const TodayQuizSection: React.FC = () => {
701751 </ div >
702752 ) }
703753
704- { /* 모범답안 표시 (주관식과 서술형) */ }
705- { ( displayQuiz ?. quizType === 'SUBJECTIVE ' || displayQuiz ?. quizType === 'ESSAY ' ) && (
754+ { /* 모범답안 표시 (주관식, 서술형) */ }
755+ { ( displayQuiz ?. quizType === 'SHORT_ANSWER ' || displayQuiz ?. quizType === 'SUBJECTIVE ' ) && (
706756 < div className = "p-4 bg-green-50 rounded-xl mb-6" >
707757 < h4 className = "text-lg font-bold text-gray-900 mb-2" > 모범답안</ h4 >
708758 < p className = "text-green-800 font-medium leading-relaxed" >
@@ -712,7 +762,7 @@ const TodayQuizSection: React.FC = () => {
712762 ) }
713763
714764 { /* AI 피드백 표시 (서술형만) */ }
715- { displayQuiz ?. quizType === 'ESSAY ' && (
765+ { displayQuiz ?. quizType === 'SUBJECTIVE ' && (
716766 < div className = "p-4 bg-blue-50 rounded-xl mb-6" >
717767 < h4 className = "text-lg font-bold text-gray-900 mb-2" > AI 피드백</ h4 >
718768 { ( isAiFeedbackLoading && ! feedbackResult ) || ( feedbackResult && resultChars . length === 0 ) ? (
0 commit comments