Rename MC to MultipleChoice, implement SingleChoice option, and update documentation
This commit is contained in:
+14
-14
@@ -90,8 +90,8 @@ function Leaderboard({ entries, highlight, compact }) {
|
||||
const ANSWER_COLORS = { A: 'answer-a', B: 'answer-b', C: 'answer-c', D: 'answer-d' };
|
||||
|
||||
function AnswerGrid({ question, selected, onToggle, disabled, feedback }) {
|
||||
const typ = (question.typ || 'MC').toLowerCase();
|
||||
const isWF = typ === 'wahr/falsch';
|
||||
const typ = (question.typ || 'MultipleChoice').toLowerCase();
|
||||
const isSingle = typ === 'wahr/falsch' || typ === 'singlechoice';
|
||||
|
||||
if (typ === 'freitext') {
|
||||
if (feedback) {
|
||||
@@ -132,7 +132,7 @@ function AnswerGrid({ question, selected, onToggle, disabled, feedback }) {
|
||||
<button key={a.key} className={cls} disabled={disabled || !!feedback}
|
||||
onClick={() => {
|
||||
if (disabled || feedback) return;
|
||||
if (isWF) onToggle([a.key]);
|
||||
if (isSingle) onToggle([a.key]);
|
||||
else onToggle(isSelected ? selected.filter((s) => s !== a.key) : [...selected, a.key]);
|
||||
}}>
|
||||
{icon}{a.text}
|
||||
@@ -503,10 +503,10 @@ function SoloQuizPage({ params, navigate }) {
|
||||
if (!questions.length) return <div className="min-h-screen flex items-center justify-center animate-pulse text-xl text-amber-400">Lade Fragen...</div>;
|
||||
|
||||
const q = questions[index];
|
||||
const typ = fieldVal(q['Typ'], 'MC').toLowerCase();
|
||||
const typ = fieldVal(q['Typ'], 'MultipleChoice').toLowerCase();
|
||||
const sanitized = {
|
||||
frage: q['Frage'] || '(Kein Fragetext)',
|
||||
typ: fieldVal(q['Typ'], 'MC'),
|
||||
typ: fieldVal(q['Typ'], 'MultipleChoice'),
|
||||
bild: q['Bild'] && Array.isArray(q['Bild']) && q['Bild'].length ? q['Bild'][0].url : null,
|
||||
antworten: shuffledAnswers,
|
||||
};
|
||||
@@ -838,7 +838,7 @@ function WettkampfQuizPage({ params, navigate }) {
|
||||
// Detect all unique types dynamically
|
||||
const typeGroups = {};
|
||||
shuffled.forEach((q) => {
|
||||
const typ = fieldVal(q['Typ'], 'MC');
|
||||
const typ = fieldVal(q['Typ'], 'MultipleChoice');
|
||||
if (!typeGroups[typ]) typeGroups[typ] = [];
|
||||
typeGroups[typ].push(q);
|
||||
});
|
||||
@@ -909,7 +909,7 @@ function WettkampfQuizPage({ params, navigate }) {
|
||||
if (questions.length === 0) return;
|
||||
const map = {};
|
||||
questions.forEach((q) => {
|
||||
const typ = fieldVal(q['Typ'], 'MC').toLowerCase();
|
||||
const typ = fieldVal(q['Typ'], 'MultipleChoice').toLowerCase();
|
||||
if (typ !== 'freitext') {
|
||||
const antworten = [];
|
||||
['A', 'B', 'C', 'D'].forEach((k) => { if (q[`Antwort ${k}`]) antworten.push({ key: k, text: q[`Antwort ${k}`] }); });
|
||||
@@ -1026,7 +1026,7 @@ function WettkampfQuizPage({ params, navigate }) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typ = fieldVal(question['Typ'], 'MC').toLowerCase();
|
||||
const typ = fieldVal(question['Typ'], 'MultipleChoice').toLowerCase();
|
||||
const rawCorrect = (question['Richtige Antwort'] || '').trim();
|
||||
let ok = false;
|
||||
|
||||
@@ -1136,13 +1136,13 @@ function WettkampfQuizPage({ params, navigate }) {
|
||||
|
||||
const currentAnswer = answers[q?.id];
|
||||
const currentSelected = currentAnswer?.selected || [];
|
||||
const typ = fieldVal(q['Typ'], 'MC').toLowerCase();
|
||||
const isWF = typ === 'wahr/falsch';
|
||||
const typ = fieldVal(q['Typ'], 'MultipleChoice').toLowerCase();
|
||||
const isSingle = typ === 'wahr/falsch' || typ === 'singlechoice';
|
||||
const currentShuffledAnswers = shuffledAnswersMap[q?.id] || [];
|
||||
|
||||
const sanitized = {
|
||||
frage: q['Frage'] || '(Kein Fragetext)',
|
||||
typ: fieldVal(q['Typ'], 'MC'),
|
||||
typ: fieldVal(q['Typ'], 'MultipleChoice'),
|
||||
bild: q['Bild'] && Array.isArray(q['Bild']) && q['Bild'].length ? q['Bild'][0].url : null,
|
||||
antworten: currentShuffledAnswers,
|
||||
};
|
||||
@@ -1240,7 +1240,7 @@ function WettkampfQuizPage({ params, navigate }) {
|
||||
return (
|
||||
<button key={a.key} className={cls}
|
||||
onClick={() => {
|
||||
if (isWF) handleSelect(q.id, [a.key]);
|
||||
if (isSingle) handleSelect(q.id, [a.key]);
|
||||
else handleSelect(q.id, isSelected ? currentSelected.filter((s) => s !== a.key) : [...currentSelected, a.key]);
|
||||
}}>
|
||||
{a.text}
|
||||
@@ -1304,7 +1304,7 @@ function WettkampfResultPage({ params, navigate }) {
|
||||
// Resolve correct answers for a question
|
||||
const resolveCorrectKeys = (question) => {
|
||||
const rawCorrect = (question['Richtige Antwort'] || '').trim();
|
||||
const typ = fieldVal(question['Typ'], 'MC').toLowerCase();
|
||||
const typ = fieldVal(question['Typ'], 'MultipleChoice').toLowerCase();
|
||||
if (typ === 'freitext') return { keys: [], text: rawCorrect };
|
||||
|
||||
const parts = rawCorrect.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
@@ -1326,7 +1326,7 @@ function WettkampfResultPage({ params, navigate }) {
|
||||
const QuestionReview = ({ result }) => {
|
||||
const question = qMap[result.questionId];
|
||||
if (!question) return null;
|
||||
const typ = fieldVal(question['Typ'], 'MC').toLowerCase();
|
||||
const typ = fieldVal(question['Typ'], 'MultipleChoice').toLowerCase();
|
||||
const userAnswer = answers[result.questionId];
|
||||
const selected = userAnswer?.selected || [];
|
||||
const { keys: correctKeys, text: correctText } = resolveCorrectKeys(question);
|
||||
|
||||
Reference in New Issue
Block a user