Resolved answer mapping & formatting: Enhanced quiz-logic to handle text-to-key answer resolution and updated app.js indentation/logic.
This commit is contained in:
+38
-6
@@ -507,17 +507,49 @@ function SoloQuizPage({ params, navigate }) {
|
||||
|
||||
const checkAnswer = () => {
|
||||
const rawCorrect = (q['Richtige Antwort'] || '').trim();
|
||||
let correct, ok;
|
||||
let correctKeysResolved, ok;
|
||||
|
||||
if (typ === 'freitext') {
|
||||
correct = []; setCorrectText(rawCorrect);
|
||||
correctKeysResolved = [];
|
||||
setCorrectText(rawCorrect);
|
||||
ok = normalizeText(selected[0]) === normalizeText(rawCorrect);
|
||||
} else {
|
||||
correct = rawCorrect.split(',').map((s) => s.trim().toUpperCase()).filter(Boolean);
|
||||
const correctSet = new Set(correct);
|
||||
// Resolve correct answer: could be keys ("A","B") or text ("Wahr","Falsch")
|
||||
const parts = rawCorrect.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
const validKeys = new Set(['A', 'B', 'C', 'D']);
|
||||
const allAreKeys = parts.length > 0 && parts.every((p) => validKeys.has(p.toUpperCase()));
|
||||
|
||||
if (allAreKeys) {
|
||||
correctKeysResolved = parts.map((p) => p.toUpperCase());
|
||||
} else {
|
||||
// Match text against answer options
|
||||
correctKeysResolved = [];
|
||||
for (const part of parts) {
|
||||
const partLower = part.toLowerCase().trim();
|
||||
// Search in all answers (including shuffled ones which keep their original keys)
|
||||
const allAnswers = [];
|
||||
['A', 'B', 'C', 'D'].forEach((k) => {
|
||||
if (q[`Antwort ${k}`]) allAnswers.push({ key: k, text: q[`Antwort ${k}`] });
|
||||
});
|
||||
for (const ans of allAnswers) {
|
||||
if (ans.text.toLowerCase().trim() === partLower) {
|
||||
correctKeysResolved.push(ans.key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback
|
||||
if (correctKeysResolved.length === 0) {
|
||||
correctKeysResolved = parts.map((p) => p.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
const correctSet = new Set(correctKeysResolved);
|
||||
const selectedSet = new Set(selected.map((s) => s.toUpperCase()));
|
||||
ok = correct.length === selectedSet.size && correct.every((c) => selectedSet.has(c));
|
||||
ok = correctKeysResolved.length === selectedSet.size && correctKeysResolved.every((c) => selectedSet.has(c));
|
||||
}
|
||||
setCorrectKeys(correct);
|
||||
|
||||
setCorrectKeys(correctKeysResolved);
|
||||
setIsCorrect(ok);
|
||||
setShowFeedback(true);
|
||||
|
||||
|
||||
+40
-5
@@ -25,14 +25,50 @@ function checkFreitext(userAnswer, correctAnswer) {
|
||||
return normalizeText(userAnswer) === normalizeText(correctAnswer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve correct answer(s) to keys (A/B/C/D).
|
||||
* Handles both:
|
||||
* - "A" or "A,C" (key-based)
|
||||
* - "Falsch" or "Stuttgart" (text-based → resolved to matching key)
|
||||
*/
|
||||
function parseCorrectAnswers(question) {
|
||||
const raw = (question['Richtige Antwort'] || '').trim();
|
||||
const typ = getTyp(question);
|
||||
if (typ === 'freitext') return [raw];
|
||||
return raw
|
||||
.split(',')
|
||||
.map((s) => s.trim().toUpperCase())
|
||||
.filter(Boolean);
|
||||
|
||||
const parts = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
const validKeys = new Set(['A', 'B', 'C', 'D']);
|
||||
|
||||
// Check if all parts are valid keys already
|
||||
const allAreKeys = parts.length > 0 && parts.every((p) => validKeys.has(p.toUpperCase()));
|
||||
if (allAreKeys) {
|
||||
return parts.map((p) => p.toUpperCase());
|
||||
}
|
||||
|
||||
// Otherwise: try to match each part against the answer texts
|
||||
const resolved = [];
|
||||
for (const part of parts) {
|
||||
const partLower = part.toLowerCase().trim();
|
||||
const keys = ['A', 'B', 'C', 'D'];
|
||||
let found = false;
|
||||
for (const k of keys) {
|
||||
const answerText = (question[`Antwort ${k}`] || '').trim();
|
||||
if (answerText && answerText.toLowerCase() === partLower) {
|
||||
resolved.push(k);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If it looks like a key anyway (single char), use it
|
||||
if (!found && part.length === 1 && validKeys.has(part.toUpperCase())) {
|
||||
resolved.push(part.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
if (resolved.length > 0) return resolved;
|
||||
|
||||
// Fallback: return as-is uppercase
|
||||
return parts.map((p) => p.toUpperCase());
|
||||
}
|
||||
|
||||
function countOptions(question) {
|
||||
@@ -104,7 +140,6 @@ function sanitizeQuestion(question) {
|
||||
kategorie: extractFieldValue(question['Kategorie'], ''),
|
||||
};
|
||||
|
||||
// Rewrite image URL to use proxy
|
||||
const bild = question['Bild'];
|
||||
if (bild && Array.isArray(bild) && bild.length > 0 && bild[0].url) {
|
||||
sanitized.bild = `/api/img?url=${encodeURIComponent(bild[0].url)}`;
|
||||
|
||||
Reference in New Issue
Block a user