Implement Vue quiz screen and fix route authority

This commit is contained in:
jieun committed 2026-10-20 21:20:28 +09:00
1 parent aaa051c7f7
commit 392ac642b0
4 files changed
+250

No files matched your search

+100
View File
@@ -0,0 +1,100 @@
import { defineComponent, onMounted, ref } from 'vue';
import {
type ExamQuestionView,
type ExamResult,
type OptionKey,
type SubjectItem,
fetchActiveSubjects,
loadQuestions,
startExam,
submitExam,
} from './quiz.service';
export default defineComponent({
name: 'QuizView',
setup() {
const subjects = ref<SubjectItem[]>([]);
const selectedSubjectId = ref<number | null>(null);
const attemptId = ref<number | null>(null);
const questions = ref<ExamQuestionView[]>([]);
const selectedAnswers = ref<Record<number, OptionKey | null>>({});
const result = ref<ExamResult | null>(null);
const errorMessage = ref<string | null>(null);
const loading = ref(false);
onMounted(async () => {
try {
subjects.value = await fetchActiveSubjects();
} catch {
errorMessage.value = '과목 목록을 불러오지 못했습니다.';
}
});
const handleStartExam = async () => {
if (!selectedSubjectId.value) return;
errorMessage.value = null;
loading.value = true;
try {
const started = await startExam(selectedSubjectId.value);
attemptId.value = started.attemptId;
const loadedQuestions = await loadQuestions(started.attemptId);
questions.value = loadedQuestions;
selectedAnswers.value = {};
loadedQuestions.forEach(q => {
selectedAnswers.value[q.questionId] = null;
});
} catch (err: any) {
errorMessage.value = err?.response?.data?.detail || '응시를 시작할 수 없습니다.';
attemptId.value = null;
} finally {
loading.value = false;
}
};
const handleSubmitExam = async () => {
if (!attemptId.value) return;
errorMessage.value = null;
loading.value = true;
try {
const payload = questions.value.map(q => ({
questionId: q.questionId,
selectedOption: selectedAnswers.value[q.questionId] ?? null,
}));
result.value = await submitExam(attemptId.value, payload);
} catch (err: any) {
errorMessage.value = err?.response?.data?.detail || '답안 제출 중 오류가 발생했습니다.';
} finally {
loading.value = false;
}
};
const resetQuiz = () => {
attemptId.value = null;
questions.value = [];
selectedAnswers.value = {};
result.value = null;
errorMessage.value = null;
};
return {
subjects,
selectedSubjectId,
attemptId,
questions,
selectedAnswers,
result,
errorMessage,
loading,
handleStartExam,
handleSubmitExam,
resetQuiz,
};
},
});