fix: QuizInterface crash on undefined text_content - add null guards and safe optional chaining

This commit is contained in:
jeremy bayse
2026-04-14 19:09:58 +02:00
parent 107e2d0a1d
commit af4502859b

View File

@@ -10,7 +10,7 @@ const props = defineProps({
const currentQuestionIndex = ref(0); const currentQuestionIndex = ref(0);
const answers = ref({}); const answers = ref({});
const timeLeft = ref(props.quiz.duration_minutes * 60); const timeLeft = ref(props.quiz?.duration_minutes ? props.quiz.duration_minutes * 60 : 0);
let timer = null; let timer = null;
// Initialize answers from existing attempt answers if any // Initialize answers from existing attempt answers if any
@@ -58,8 +58,8 @@ const formatTime = (seconds) => {
return `${mins}:${secs.toString().padStart(2, '0')}`; return `${mins}:${secs.toString().padStart(2, '0')}`;
}; };
const currentQuestion = computed(() => props.quiz.questions[currentQuestionIndex.value]); const currentQuestion = computed(() => props.quiz.questions?.[currentQuestionIndex.value] ?? null);
const progress = computed(() => ((currentQuestionIndex.value + 1) / props.quiz.questions.length) * 100); const progress = computed(() => props.quiz.questions?.length ? ((currentQuestionIndex.value + 1) / props.quiz.questions.length) * 100 : 0);
const saveAnswer = async () => { const saveAnswer = async () => {
const qid = currentQuestion.value.id; const qid = currentQuestion.value.id;
@@ -150,8 +150,11 @@ const finishQuiz = () => {
<!-- Main Content --> <!-- Main Content -->
<main class="flex-1 flex flex-col items-center justify-center p-8"> <main class="flex-1 flex flex-col items-center justify-center p-8">
<div class="w-full max-w-3xl"> <div class="w-full max-w-3xl">
<!-- Guard: wait until question is loaded -->
<div v-if="!currentQuestion" class="text-center text-slate-400 italic">Chargement de la question...</div>
<!-- Question Card --> <!-- Question Card -->
<div class="bg-slate-800/50 backdrop-blur-xl rounded-3xl p-8 sm:p-12 border border-slate-700 shadow-2xl relative overflow-hidden group"> <div v-else class="bg-slate-800/50 backdrop-blur-xl rounded-3xl p-8 sm:p-12 border border-slate-700 shadow-2xl relative overflow-hidden group">
<!-- Subtle background glow --> <!-- Subtle background glow -->
<div class="absolute -top-24 -right-24 w-64 h-64 bg-indigo-600/10 blur-[100px] rounded-full group-hover:bg-indigo-600/20 transition-all duration-700"></div> <div class="absolute -top-24 -right-24 w-64 h-64 bg-indigo-600/10 blur-[100px] rounded-full group-hover:bg-indigo-600/20 transition-all duration-700"></div>
@@ -202,7 +205,8 @@ const finishQuiz = () => {
<textarea <textarea
class="w-full h-48 bg-slate-700/30 border border-slate-600 rounded-2xl p-6 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all outline-none resize-none text-lg" class="w-full h-48 bg-slate-700/30 border border-slate-600 rounded-2xl p-6 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all outline-none resize-none text-lg"
placeholder="Saisissez votre réponse ici..." placeholder="Saisissez votre réponse ici..."
v-model="answers[currentQuestion.id].text_content" :value="answers[currentQuestion.id]?.text_content ?? ''"
@input="updateOpenAnswer($event.target.value)"
@blur="saveAnswer" @blur="saveAnswer"
></textarea> ></textarea>
</div> </div>