diff --git a/backend/services/vocabService.js b/backend/services/vocabService.js index 5ae6de7..0cb2332 100644 --- a/backend/services/vocabService.js +++ b/backend/services/vocabService.js @@ -1405,15 +1405,30 @@ export default class VocabService { let correctAnswer = null; let alternatives = []; - // Für Multiple Choice: Extrahiere die richtige Antwort aus dem Index + // Für Multiple Choice: Extrahiere die richtige(n) Antwort(en) aus dem Index/den Indizes if (exercise.exerciseTypeId === 2 && answerData.correctAnswer !== undefined) { const options = questionData?.options || []; - const correctIndex = answerData.correctAnswer; - if (options[correctIndex] !== undefined) { - correctAnswer = options[correctIndex]; + + // Unterstütze sowohl einzelne korrekte Antwort als auch Array von korrekten Antworten + let correctIndices = []; + if (Array.isArray(answerData.correctAnswer)) { + correctIndices = answerData.correctAnswer.map(idx => Number(idx)); + } else { + correctIndices = [Number(answerData.correctAnswer)]; } - // Alternativen sind alle anderen Optionen - alternatives = options.filter((opt, idx) => idx !== correctIndex); + + // Extrahiere alle korrekten Antworten + const correctAnswersList = correctIndices + .map(idx => options[idx]) + .filter(opt => opt !== undefined); + + if (correctAnswersList.length > 0) { + // Wenn mehrere richtige Antworten: Zeige alle an, getrennt durch " / " + correctAnswer = correctAnswersList.join(' / '); + } + + // Alternativen sind alle anderen Optionen (nicht korrekte) + alternatives = options.filter((opt, idx) => !correctIndices.includes(idx)); } // Für Gap Fill: Extrahiere aus answers Array else if (exercise.exerciseTypeId === 1 && answerData.answers) { @@ -1460,14 +1475,32 @@ export default class VocabService { const parsedAnswerData = typeof answerData === 'string' ? JSON.parse(answerData) : answerData; const parsedQuestionData = typeof questionData === 'string' ? JSON.parse(questionData) : questionData; - // Für Multiple Choice: Prüfe ob userAnswer (Index) mit correctAnswer (Index) übereinstimmt + // Für Multiple Choice: Prüfe ob userAnswer (Index) mit correctAnswer (Index oder Array von Indizes) übereinstimmt if (exerciseTypeId === 2) { // multiple_choice - const correctIndex = parsedAnswerData.correctAnswer !== undefined - ? parsedAnswerData.correctAnswer - : (parsedAnswerData.correct !== undefined ? parsedAnswerData.correct : null); - if (correctIndex === null) return false; + // Unterstütze sowohl einzelne korrekte Antwort als auch Array von korrekten Antworten + let correctIndices = []; + + if (parsedAnswerData.correctAnswer !== undefined) { + // Kann ein einzelner Index oder ein Array von Indizes sein + if (Array.isArray(parsedAnswerData.correctAnswer)) { + correctIndices = parsedAnswerData.correctAnswer.map(idx => Number(idx)); + } else { + correctIndices = [Number(parsedAnswerData.correctAnswer)]; + } + } else if (parsedAnswerData.correct !== undefined) { + // Fallback: Prüfe auch 'correct' Feld + if (Array.isArray(parsedAnswerData.correct)) { + correctIndices = parsedAnswerData.correct.map(idx => Number(idx)); + } else { + correctIndices = [Number(parsedAnswerData.correct)]; + } + } + + if (correctIndices.length === 0) return false; + // userAnswer ist der Index (0, 1, 2, ...) - return Number(userAnswer) === Number(correctIndex); + const userIndex = Number(userAnswer); + return correctIndices.includes(userIndex); } // Für Lückentext: Normalisiere und vergleiche diff --git a/frontend/src/views/social/VocabCourseView.vue b/frontend/src/views/social/VocabCourseView.vue index 153e724..f753b57 100644 --- a/frontend/src/views/social/VocabCourseView.vue +++ b/frontend/src/views/social/VocabCourseView.vue @@ -257,6 +257,11 @@ export default { table-layout: fixed; } +.lessons-table th, +.lessons-table td { + box-sizing: border-box; +} + .lessons-table thead { background: #f8f9fa; } @@ -276,12 +281,14 @@ export default { width: 80px; min-width: 80px; max-width: 80px; + overflow: visible; } .lessons-table th.col-title, .lessons-table td.lesson-title { width: auto; min-width: 200px; + overflow: visible; } .lessons-table th.col-status, @@ -289,6 +296,8 @@ export default { width: 200px; min-width: 200px; max-width: 200px; + overflow: visible; + word-wrap: break-word; } .lessons-table th.col-actions, @@ -296,6 +305,7 @@ export default { width: 250px; min-width: 250px; max-width: 250px; + overflow: visible; } .lessons-table tbody tr { @@ -308,13 +318,15 @@ export default { .lessons-table td { padding: 15px; - vertical-align: middle; + vertical-align: top; } .lesson-number { font-weight: 600; color: #666; font-size: 0.95em; + vertical-align: top; + padding-top: 15px; } .lesson-title { @@ -340,11 +352,9 @@ export default { flex-direction: column; gap: 5px; align-items: flex-start; - justify-content: center; - min-height: 60px; + justify-content: flex-start; white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + overflow: visible; } .badge.completed { @@ -372,7 +382,7 @@ export default { display: flex; gap: 8px; flex-wrap: wrap; - align-items: center; + align-items: flex-start; justify-content: flex-start; }