[FEATURE] Ajout des rétroactions pour les questions à choix multiples et réponses courtes

Fixes #291
This commit is contained in:
JubaAzul 2025-03-13 18:50:29 -04:00
parent 112062c0b2
commit 61a5cf1330
6 changed files with 168 additions and 50 deletions

View file

@ -16,10 +16,11 @@ interface Props {
const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
const { question, showAnswer, handleOnSubmitAnswer, passedAnswer } = props;
const [answer, setAnswer] = useState<AnswerType>(passedAnswer || '');
const [isGoodAnswer, setisGoodAnswer] = useState<boolean>(false);
let disableButton = false;
if(handleOnSubmitAnswer === undefined){
if (handleOnSubmitAnswer === undefined) {
disableButton = true;
}
@ -29,6 +30,15 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
}
}, [passedAnswer]);
useEffect(() => {
checkAnswer();
}, [answer]);
const checkAnswer = () => {
const isCorrect = question.choices.some((choice) => choice.formattedText.text === answer as string);
setisGoodAnswer(isCorrect);
};
const handleOnClickAnswer = (choice: string) => {
setAnswer(choice);
};
@ -36,7 +46,19 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
const alphabet = alpha.map((x) => String.fromCharCode(x));
return (
<div className="question-container">
<div className="question-wrapper">
{showAnswer && (
<div>
<div className='question-feedback-validation'>
{isGoodAnswer ? '✅ Correct! ' : '❌ Incorrect!'}
</div>
<div className="question-title">
Question :
</div>
</div>
)}
<div className="question content">
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedStem) }} />
</div>
@ -51,8 +73,8 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
className="button-wrapper"
disabled={disableButton}
onClick={() => !showAnswer && handleOnClickAnswer(choice.formattedText.text)}>
{showAnswer? (<div> {(choice.isCorrect ? '✅' : '❌')}</div>)
:``}
{showAnswer ? (<div> {(choice.isCorrect ? '✅' : '❌')}</div>)
: ``}
<div className={`circle ${selected}`}>{alphabet[i]}</div>
<div className={`answer-text ${selected}`}>
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedText) }} />

View file

@ -18,6 +18,7 @@ const NumericalQuestionDisplay: React.FC<Props> = (props) => {
const { question, showAnswer, handleOnSubmitAnswer, passedAnswer } =
props;
const [answer, setAnswer] = useState<AnswerType>(passedAnswer || '');
const [isGoodAnswer, setisGoodAnswer] = useState<boolean>(false);
const correctAnswers = question.choices;
let correctAnswer = '';
@ -27,6 +28,14 @@ const NumericalQuestionDisplay: React.FC<Props> = (props) => {
}
}, [passedAnswer]);
useEffect(() => {
checkAnswer();
}, [answer]);
const checkAnswer = () => {
const isCorrect = correctAnswer === answer;
setisGoodAnswer(isCorrect);
};
//const isSingleAnswer = correctAnswers.length === 1;
if (isSimpleNumericalAnswer(correctAnswers[0])) {
@ -45,21 +54,40 @@ const NumericalQuestionDisplay: React.FC<Props> = (props) => {
return (
<div className="question-wrapper">
{showAnswer && (
<div>
<div className='question-feedback-validation'>
{isGoodAnswer ? '✅ Correct! ' : '❌ Incorrect!'}
</div>
<div className="question-title">
Question :
</div>
</div>
)}
<div>
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedStem) }} />
</div>
{showAnswer ? (
<>
<div className="correct-answer-text mb-2">
<strong>La bonne réponse est: </strong>
{correctAnswer}</div>
<span>
<strong>Votre réponse est: </strong>{answer.toString()}
</span>
<div className="correct-answer-text mb-1">
<div>
<div className="question-title">
Réponse(s) accepté(es):
</div>
<div className="accepted-answers">
{correctAnswer}
</div>
</div>
<div>
<div className="question-title">
Votre réponse est: </div>
<div className="accepted-answers">{answer}</div>
</div>
</div>
{question.formattedGlobalFeedback && <div className="global-feedback mb-2">
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedGlobalFeedback) }} />
</div>}
</>
) : (
<>

View file

@ -17,34 +17,59 @@ const ShortAnswerQuestionDisplay: React.FC<Props> = (props) => {
const { question, showAnswer, handleOnSubmitAnswer, passedAnswer } = props;
const [answer, setAnswer] = useState<AnswerType>(passedAnswer || '');
const [isGoodAnswer, setisGoodAnswer] = useState<boolean>(false);
useEffect(() => {
if (passedAnswer !== undefined) {
setAnswer(passedAnswer);
}
}, [passedAnswer]);
console.log("Answer" , answer);
useEffect(() => {
checkAnswer();
}, [answer]);
const checkAnswer = () => {
const isCorrect = question.choices.some((choice) => choice.text.toLowerCase() === (answer as String).toLowerCase());
setisGoodAnswer(isCorrect);
};
return (
<div className="question-wrapper">
<div className="question content">
{showAnswer && (
<div>
<div className='question-feedback-validation'>
{isGoodAnswer ? '✅ Correct! ' : '❌ Incorrect!'}
</div>
<div className="question-title">
Question :
</div>
</div>
)}
<div>
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedStem) }} />
</div>
{showAnswer ? (
<>
<div className="correct-answer-text mb-1">
<span>
<strong>La bonne réponse est: </strong>
<div>
<div className="question-title">
Réponse(s) accepté(es):
</div>
{question.choices.map((choice) => (
<div key={choice.text} className="mb-1">
<div key={choice.text} className="accepted-answers">
{choice.text}
</div>
))}
</span>
<span>
<strong>Votre réponse est: </strong>{answer}
</span>
</div>
<div>
<div className="question-title">
Votre réponse est: </div>
<div className="accepted-answers">{answer}</div>
</div>
</div>
{question.formattedGlobalFeedback && <div className="global-feedback mb-2">
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedGlobalFeedback) }} />

View file

@ -47,7 +47,19 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
const selectedTrue = answer ? 'selected' : '';
const selectedFalse = answer !== undefined && !answer ? 'selected' : '';
return (
<div className="question-container">
<div className="question-wrapper">
{showAnswer && (
<div>
<div className='question-feedback-validation'>
{question.isTrue? '✅ Correct! ' : '❌ Incorrect!'}
</div>
<div className="question-title">
Question :
</div>
</div>
)}
<div className="question content">
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedStem) }} />
</div>

View file

@ -2,7 +2,6 @@
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
}
@ -22,7 +21,6 @@
.question-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
@ -136,12 +134,12 @@
/* height: 1em; */
}
.global-feedback {
position: relative;
padding: 0 1rem;
background-color: hsl(43, 100%, 94%);
color: hsl(43, 95%, 9%);
margin-top: 2rem;
border: hsl(36, 84%, 93%) 1px solid;
border-radius: 6px;
box-shadow: 0px 2px 5px hsl(0, 0%, 74%);
@ -169,3 +167,39 @@
.choices-wrapper {
width: 90%;
}
.correct-answer-text {
text-align: left; /* Align text to the left */
width: 100%; /* Ensure it takes the full width of its container */
}
.accepted-answers {
display: inline-block; /* Display elements side by side */
border-radius: 6px; /* Add rounded corners */
padding: 0.5rem; /* Add padding for spacing */
margin: 0.5rem; /* Add margin for spacing between elements */
background-color: hsl(0, 0%, 87%); /* Optional: Add a background color for emphasis */
}
.question-feedback-validation{
font-size: 1.8rem; /* Increase the font size */
font-weight: bold; /* Make the text bold */
width: 100%;
height: 100%;
margin: 0 auto;
}
.question-title{
margin-bottom: 0.5rem;
margin-top: 1.5rem;
width: 100%;
font-weight: bold;
}
.question-content{
margin-bottom: 1rem;
}

View file

@ -4,7 +4,7 @@ import QuestionComponent from '../QuestionsDisplay/QuestionDisplay';
import '../../pages/Student/JoinRoom/joinRoom.css';
import { QuestionType } from '../../Types/QuestionType';
import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton';
import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';
import { Dialog, DialogContent, DialogActions, Button } from '@mui/material';
import { Question } from 'gift-pegjs';
import { AnswerSubmissionToBackendType } from 'src/services/WebsocketService';
import { AnswerType } from 'src/pages/Student/JoinRoom/JoinRoom';
@ -94,7 +94,6 @@ const TeacherModeQuiz: React.FC<TeacherModeQuizProps> = ({
open={isFeedbackDialogOpen}
onClose={handleFeedbackDialogClose}
>
<DialogTitle>Rétroaction</DialogTitle>
<DialogContent>
<div style={{
wordWrap: 'break-word',
@ -102,8 +101,6 @@ const TeacherModeQuiz: React.FC<TeacherModeQuizProps> = ({
maxHeight: '400px',
overflowY: 'auto',
}}>
<div style={{ textAlign: 'left', fontWeight: 'bold', marginTop: '10px' }}
>Question : </div>
</div>
<QuestionComponent