Compare commits

..

No commits in common. "800575a79c350695a73ef3a3d6b6e271d35f8019" and "0f52440946a268ce4b95e1fd5f4d0b808198b9c0" have entirely different histories.

View file

@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react';
import '../questionStyle.css'; import '../questionStyle.css';
import { Button, TextField } from '@mui/material'; import { Button, TextField } from '@mui/material';
import { FormattedTextTemplate } from '../../GiftTemplate/templates/TextTypeTemplate'; import { FormattedTextTemplate } from '../../GiftTemplate/templates/TextTypeTemplate';
import { MultipleNumericalAnswer, NumericalQuestion } from 'gift-pegjs'; import { NumericalQuestion, SimpleNumericalAnswer, RangeNumericalAnswer, HighLowNumericalAnswer } from 'gift-pegjs';
import { isSimpleNumericalAnswer, isRangeNumericalAnswer, isHighLowNumericalAnswer, isMultipleNumericalAnswer } from 'gift-pegjs/typeGuards'; import { isSimpleNumericalAnswer, isRangeNumericalAnswer, isHighLowNumericalAnswer, isMultipleNumericalAnswer } from 'gift-pegjs/typeGuards';
import { AnswerType } from 'src/pages/Student/JoinRoom/JoinRoom'; import { AnswerType } from 'src/pages/Student/JoinRoom/JoinRoom';
@ -19,11 +19,13 @@ const NumericalQuestionDisplay: React.FC<Props> = (props) => {
props; props;
const [answer, setAnswer] = useState<AnswerType>(passedAnswer || ''); const [answer, setAnswer] = useState<AnswerType>(passedAnswer || '');
const [isGoodAnswer, setisGoodAnswer] = useState<boolean>(false); const [isGoodAnswer, setisGoodAnswer] = useState<boolean>(false);
let isMultpleAnswer = false; const [isMultpleAnswer, setIsMultpleAnswer] = useState<boolean>(false);
const correctAnswers = question.choices;
const correctAnswersPhrases: string[] = [];
let correctAnswer = '';
const correctAnswers = question.choices;
const correctAnswersList: number[] = [];
const correctAnswersPhrases: string[] = [];
let correctAnswer = '';
useEffect(() => { useEffect(() => {
if (passedAnswer !== null && passedAnswer !== undefined) { if (passedAnswer !== null && passedAnswer !== undefined) {
@ -35,67 +37,54 @@ const NumericalQuestionDisplay: React.FC<Props> = (props) => {
checkAnswer(); checkAnswer();
}, [answer]); }, [answer]);
const isValidWeight = (weight?: number) => weight === undefined || weight > 0;
const isAnswerCorrect = (answer: number, correctAnswer: any): boolean => {
if (isSimpleNumericalAnswer(correctAnswer)) {
return answer === correctAnswer.number;
} else if (isRangeNumericalAnswer(correctAnswer)) {
return (
answer >= correctAnswer.number - correctAnswer.range &&
answer <= correctAnswer.number + correctAnswer.range
);
} else if (isHighLowNumericalAnswer(correctAnswer)) {
return (
answer >= correctAnswer.numberLow &&
answer <= correctAnswer.numberHigh
);
}
return false;
};
const formatCorrectAnswer = (correctAnswer: any): string => {
if (isSimpleNumericalAnswer(correctAnswer)) {
return `${correctAnswer.number}`;
} else if (isRangeNumericalAnswer(correctAnswer)) {
return `Entre ${correctAnswer.number - correctAnswer.range} et ${correctAnswer.number + correctAnswer.range}`;
} else if (isHighLowNumericalAnswer(correctAnswer)) {
return `Entre ${correctAnswer.numberLow} et ${correctAnswer.numberHigh}`;
}
return '';
};
const checkAnswer = () => { const checkAnswer = () => {
if(isMultpleAnswer) { if(isMultpleAnswer) {
correctAnswers.forEach((answers) => { correctAnswers.forEach((answers) => {
if ( if(isSimpleNumericalAnswer(answers) && answer === answers.number) {
isMultipleNumericalAnswer(answers) && setisGoodAnswer(true);
isValidWeight(answers.weight) && } else if(isRangeNumericalAnswer(answers) && answer as number >= answers.number - answers.range && answer as number <= answers.number + answers.range) {
isAnswerCorrect(answer as number, answers.answer) setisGoodAnswer(true);
) { } else if(isHighLowNumericalAnswer(answers) && answer as number >= answers.numberLow && answer as number <= answers.numberHigh) {
setisGoodAnswer(true); setisGoodAnswer(true);
} }
}); }
)
;
} else { } else {
const firstAnswer = correctAnswers[0]; if(isSimpleNumericalAnswer(answers) && answer === answers.number) {
if (isAnswerCorrect(answer as number, firstAnswer)) { setisGoodAnswer(true);
} else if(isRangeNumericalAnswer(answers) && answer as number >= answers.number - answers.range && answer as number <= answers.number + answers.range) {
setisGoodAnswer(true);
} else if(isHighLowNumericalAnswer(answers) && answer as number >= answers.numberLow && answer as number <= answers.numberHigh) {
setisGoodAnswer(true); setisGoodAnswer(true);
}
} }
}; };
};
if (isMultipleNumericalAnswer(correctAnswers[0])) { //const isSingleAnswer = correctAnswers.length === 1;
if (isSimpleNumericalAnswer(correctAnswers[0])) {
correctAnswer = `${(correctAnswers[0] as SimpleNumericalAnswer).number}`;
} else if (isRangeNumericalAnswer(correctAnswers[0])) {
const choice = correctAnswers[0] as RangeNumericalAnswer;
correctAnswer = `Entre ${choice.number - choice.range} et ${choice.number + choice.range}`;
} else if (isHighLowNumericalAnswer(correctAnswers[0])) {
const choice = correctAnswers[0] as HighLowNumericalAnswer;
correctAnswer = `Entre ${choice.numberLow} et ${choice.numberHigh}`;
} else if (isMultipleNumericalAnswer(correctAnswers[0])) {
setIsMultpleAnswer(true);
correctAnswers.forEach((answers) => { correctAnswers.forEach((answers) => {
if ( if(isSimpleNumericalAnswer(answers)) {
isMultipleNumericalAnswer(answers) && correctAnswersPhrases.push(`${(answers as SimpleNumericalAnswer).number}`);
isValidWeight(answers.weight) } else if(isRangeNumericalAnswer(answers)) {
) { correctAnswersPhrases.push(`Entre ${answers.number - answers.range} et ${answers.number + answers.range}`);
correctAnswersPhrases.push(formatCorrectAnswer(answers.answer)); } else if(isHighLowNumericalAnswer(answers)) {
correctAnswersPhrases.push(`Entre ${answers.numberLow} et ${answers.numberHigh}`);
} }
}); });
isMultpleAnswer = true; }
} else { else {
correctAnswer = formatCorrectAnswer(correctAnswers[0]); throw new Error('Unknown numerical answer type');
} }
return ( return (
@ -121,49 +110,14 @@ const NumericalQuestionDisplay: React.FC<Props> = (props) => {
<div className="question-title"> <div className="question-title">
Réponse(s) accepté(es): Réponse(s) accepté(es):
</div> </div>
{isMultpleAnswer ? ( <div className="accepted-answers">
correctAnswersPhrases.map((phrase) => ( {correctAnswer}
<div key={phrase} className="accepted-answers">
{phrase}
</div> </div>
))
) : (
<div className="accepted-answers">{correctAnswer}</div>
)}
</div> </div>
<div> <div>
<div className="question-title"> <div className="question-title">
Votre réponse est: </div> Votre réponse est: </div>
<span>
<div className="accepted-answers">{answer}</div> <div className="accepted-answers">{answer}</div>
{isMultpleAnswer && (() => {
const highestPriorityAnswer = correctAnswers.reduce((prev, current) => {
const prevWeight = (prev as MultipleNumericalAnswer).weight ?? -1; // Treat undefined as highest priority
const currentWeight = (current as MultipleNumericalAnswer).weight ?? -1; // Treat undefined as highest priority
// Prioritize undefined weights, otherwise compare weights numerically
if (prevWeight === -1 && currentWeight !== -1) return prev;
if (currentWeight === -1 && prevWeight !== -1) return current;
return currentWeight > prevWeight ? current : prev;
});
return isAnswerCorrect(answer as number, (highestPriorityAnswer as MultipleNumericalAnswer).answer) && (
<div>
{(highestPriorityAnswer as MultipleNumericalAnswer).formattedFeedback && (
<div className="global-feedback">
<div
dangerouslySetInnerHTML={{
__html: FormattedTextTemplate(
(highestPriorityAnswer as MultipleNumericalAnswer).formattedFeedback!
),
}}
/>
</div>
)}
</div>
);
})()}
</span>
</div> </div>
</div> </div>
{question.formattedGlobalFeedback && <div className="global-feedback mb-2"> {question.formattedGlobalFeedback && <div className="global-feedback mb-2">