From b9d79fceace60e5e476d6356bf1ad1422b4ef74e Mon Sep 17 00:00:00 2001 From: KenChanA Date: Tue, 1 Apr 2025 00:29:56 -0400 Subject: [PATCH] Fixed bootstrap format, added toggle button --- .../MultipleChoiceQuestionDisplay.tsx | 37 ++-- .../NumericalQuestionDisplay.tsx | 157 +++++++-------- .../QuestionsDisplay/QuestionDisplay.tsx | 12 +- .../ShortAnswerQuestionDisplay.tsx | 57 ++---- .../TrueFalseQuestionDisplay.tsx | 185 ++++++++---------- .../pages/Teacher/ManageRoom/ManageRoom.tsx | 17 +- 6 files changed, 215 insertions(+), 250 deletions(-) diff --git a/client/src/components/QuestionsDisplay/MultipleChoiceQuestionDisplay/MultipleChoiceQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/MultipleChoiceQuestionDisplay/MultipleChoiceQuestionDisplay.tsx index 9e055ff..1d7ac9b 100644 --- a/client/src/components/QuestionsDisplay/MultipleChoiceQuestionDisplay/MultipleChoiceQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/MultipleChoiceQuestionDisplay/MultipleChoiceQuestionDisplay.tsx @@ -14,18 +14,22 @@ interface Props { passedAnswer?: AnswerType; students?: StudentType[]; isDisplayOnly?: boolean; + showResults?: boolean; } const MultipleChoiceQuestionDisplay: React.FC = (props) => { - const { question, showAnswer, handleOnSubmitAnswer, students, isDisplayOnly, passedAnswer } = props; + const { question, showAnswer, handleOnSubmitAnswer, students, showResults, passedAnswer } = props; const [answer, setAnswer] = useState(() => { if (passedAnswer && passedAnswer.length > 0) { return passedAnswer; } return []; }); - const [pickRates, setPickRates] = useState<{ percentages: number[], counts: number[], totalCount: number }>({ percentages: [], counts: [], totalCount: 0 }); - const [showCorrectAnswers, setShowCorrectAnswers] = useState(false); + const [pickRates, setPickRates] = useState<{ percentages: number[], counts: number[], totalCount: number }>({ + percentages: [], + counts: [], + totalCount: 0 + }); let disableButton = false; if (handleOnSubmitAnswer === undefined) { @@ -52,10 +56,6 @@ const MultipleChoiceQuestionDisplay: React.FC = (props) => { } }); }; - - const toggleShowCorrectAnswers = () => { - setShowCorrectAnswers(!showCorrectAnswers); - }; const calculatePickRates = () => { if (!students || students.length === 0) { @@ -88,11 +88,12 @@ const MultipleChoiceQuestionDisplay: React.FC = (props) => { setAnswer([]); calculatePickRates(); } - }, [passedAnswer, students, question.id, showCorrectAnswers]); + }, [passedAnswer, students, question.id]); const alpha = Array.from(Array(26)).map((_e, i) => i + 65); const alphabet = alpha.map((x) => String.fromCharCode(x)); + return (
@@ -103,7 +104,7 @@ const MultipleChoiceQuestionDisplay: React.FC = (props) => {
{question.choices.map((choice, i) => { const selected = answer.includes(choice.formattedText.text) ? 'selected' : ''; - const rateStyle = showCorrectAnswers ? { + const rateStyle = showResults ? { backgroundImage: `linear-gradient(to right, ${choice.isCorrect ? 'lightgreen' : 'lightcoral'} ${pickRates.percentages[i]}%, transparent ${pickRates.percentages[i]}%)`, color: 'black' } : {}; @@ -134,7 +135,12 @@ const MultipleChoiceQuestionDisplay: React.FC = (props) => { />
)} - {showCorrectAnswers &&
{choice.isCorrect ? '✅' : '❌'} {`${pickRates.counts[i]}/${pickRates.totalCount} (${pickRates.percentages[i].toFixed(1)}%)`}
} + {showResults && pickRates.percentages.length > i && ( +
+ {choice.isCorrect ? '✅' : '❌'} + {`${pickRates.counts[i]}/${pickRates.totalCount} (${pickRates.percentages[i].toFixed(1)}%)`} +
+ )}
); @@ -162,17 +168,6 @@ const MultipleChoiceQuestionDisplay: React.FC = (props) => { )}
- {isDisplayOnly && ( -
- -
- )} ); diff --git a/client/src/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.tsx index 069eaa2..36f0a5a 100644 --- a/client/src/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.tsx @@ -14,35 +14,29 @@ interface Props { showAnswer?: boolean; passedAnswer?: AnswerType; students?: StudentType[]; - isDisplayOnly?: boolean; + showResults?: boolean; } const NumericalQuestionDisplay: React.FC = (props) => { - const { question, showAnswer, handleOnSubmitAnswer, students, passedAnswer, isDisplayOnly } = + const { question, showAnswer, handleOnSubmitAnswer, students, showResults, passedAnswer } = props; const [answer, setAnswer] = useState(passedAnswer || []); const correctAnswers = question.choices; let correctAnswer = ''; - - const [showCorrectAnswers, setShowCorrectAnswers] = useState(false); const [correctAnswerRate, setCorrectAnswerRate] = useState(0); const [submissionCounts, setSubmissionCounts] = useState({ correctSubmissions: 0, totalSubmissions: 0 }); - const toggleShowCorrectAnswers = () => { - setShowCorrectAnswers(!showCorrectAnswers); - }; - useEffect(() => { if (passedAnswer !== null && passedAnswer !== undefined) { setAnswer(passedAnswer); } - if (showCorrectAnswers && students) { + if (showResults && students) { calculateCorrectAnswerRate(); } - }, [passedAnswer, showCorrectAnswers, students]); + }, [passedAnswer, showResults, students]); const calculateCorrectAnswerRate = () => { if (!students || students.length === 0) { @@ -82,85 +76,78 @@ const NumericalQuestionDisplay: React.FC = (props) => { } return ( -
-
-
-
- {showAnswer ? ( - <> -
- La bonne réponse est: - {correctAnswer}
- - Votre réponse est: {answer.toString()} - - {question.formattedGlobalFeedback &&
-
-
} - - - ) : ( - <> -
- ) => { - setAnswer([e.target.valueAsNumber]); - }} - inputProps={{ 'data-testid': 'number-input' }} - /> -
- {question.formattedGlobalFeedback && showAnswer && ( -
-
-
- )} - {handleOnSubmitAnswer && ( - - )} - - )} - - - {isDisplayOnly && ( - <> -
- -
-
+ <> +
+
+
- Taux de réponse correcte: {submissionCounts.correctSubmissions}/{submissionCounts.totalSubmissions} +
-
-
-
- {correctAnswerRate.toFixed(1)}% + {showAnswer ? ( + <> +
+ La bonne réponse est: + {correctAnswer}
+ + Votre réponse est: {answer.toString()} + + {question.formattedGlobalFeedback &&
+
+
} + + + ) : ( + <> +
+ ) => { + setAnswer([e.target.valueAsNumber]); + }} + inputProps={{ 'data-testid': 'number-input' }} + /> +
+ {question.formattedGlobalFeedback && showAnswer && ( +
+
+
+ )} + {handleOnSubmitAnswer && ( +
+ +
+ )} + + )} +
+ {showResults && ( +
+
+ Taux de réponse correcte: {submissionCounts.correctSubmissions}/{submissionCounts.totalSubmissions} +
+
+
+
+ {correctAnswerRate.toFixed(1)}% +
-
- - )} -
+ )} +
+
+ ); }; diff --git a/client/src/components/QuestionsDisplay/QuestionDisplay.tsx b/client/src/components/QuestionsDisplay/QuestionDisplay.tsx index 8ace5fd..2979eff 100644 --- a/client/src/components/QuestionsDisplay/QuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/QuestionDisplay.tsx @@ -15,7 +15,7 @@ interface QuestionProps { handleOnSubmitAnswer?: (answer: AnswerType) => void; showAnswer?: boolean; students?: StudentType[]; - isDisplayOnly?: boolean; + showResults?: boolean; answer?: AnswerType; } @@ -24,7 +24,7 @@ const QuestionDisplay: React.FC = ({ handleOnSubmitAnswer, showAnswer, students, - isDisplayOnly = false, + showResults, answer, }) => { // const isMobile = useCheckMobileScreen(); @@ -41,7 +41,7 @@ const QuestionDisplay: React.FC = ({ handleOnSubmitAnswer={handleOnSubmitAnswer} showAnswer={showAnswer} students={students} - isDisplayOnly={isDisplayOnly} + showResults={showResults} passedAnswer={answer} /> ); @@ -54,7 +54,7 @@ const QuestionDisplay: React.FC = ({ handleOnSubmitAnswer={handleOnSubmitAnswer} showAnswer={showAnswer} students={students} - isDisplayOnly={isDisplayOnly} + showResults={showResults} passedAnswer={answer} /> ); @@ -68,7 +68,7 @@ const QuestionDisplay: React.FC = ({ showAnswer={showAnswer} passedAnswer={answer} students={students} - isDisplayOnly={isDisplayOnly} + showResults={showResults} /> ); } @@ -80,7 +80,7 @@ const QuestionDisplay: React.FC = ({ handleOnSubmitAnswer={handleOnSubmitAnswer} showAnswer={showAnswer} students={students} - isDisplayOnly={isDisplayOnly} + showResults={showResults} passedAnswer={answer} /> ); diff --git a/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx index 8ee9c15..b28ffbb 100644 --- a/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx @@ -12,33 +12,28 @@ interface Props { showAnswer?: boolean; passedAnswer?: AnswerType; students?: StudentType[]; - isDisplayOnly?: boolean; + showResults?: boolean; } const ShortAnswerQuestionDisplay: React.FC = (props) => { - const { question, showAnswer, handleOnSubmitAnswer, students, passedAnswer, isDisplayOnly } = props; + const { question, showAnswer, handleOnSubmitAnswer, students, showResults, passedAnswer } = props; const [answer, setAnswer] = useState(passedAnswer || []); - const [showCorrectAnswers, setShowCorrectAnswers] = useState(false); const [correctAnswerRate, setCorrectAnswerRate] = useState(0); const [submissionCounts, setSubmissionCounts] = useState({ correctSubmissions: 0, totalSubmissions: 0 }); - const toggleShowCorrectAnswers = () => { - setShowCorrectAnswers(!showCorrectAnswers); - }; - useEffect(() => { if (passedAnswer !== undefined) { setAnswer(passedAnswer); } - if (showCorrectAnswers && students) { + if (showResults && students) { calculateCorrectAnswerRate(); } - }, [passedAnswer, showCorrectAnswers, students, answer]); + }, [passedAnswer, showResults, students, answer]); console.log("Answer", answer); const calculateCorrectAnswerRate = () => { @@ -67,7 +62,9 @@ const ShortAnswerQuestionDisplay: React.FC = (props) => {
-
+
+
+
{showAnswer ? ( <>
@@ -104,7 +101,7 @@ const ShortAnswerQuestionDisplay: React.FC = (props) => { />
{handleOnSubmitAnswer && ( -
+
- {isDisplayOnly && ( - <> -
- - {showCorrectAnswers && ( -
-
- Taux de réponse correcte: {submissionCounts.correctSubmissions}/{submissionCounts.totalSubmissions} -
-
-
-
- {correctAnswerRate.toFixed(1)}% -
-
-
- )} + {showResults && ( +
+
+ Taux de réponse correcte: {submissionCounts.correctSubmissions}/{submissionCounts.totalSubmissions}
- - )} +
+
+
+ {correctAnswerRate.toFixed(1)}% +
+
+
+ )}
diff --git a/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx index 356b376..a961b6e 100644 --- a/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx @@ -13,11 +13,11 @@ interface Props { showAnswer?: boolean; passedAnswer?: AnswerType; students?: StudentType[]; - isDisplayOnly?: boolean; + showResults?: boolean; } const TrueFalseQuestionDisplay: React.FC = (props) => { - const { question, showAnswer, handleOnSubmitAnswer, students, passedAnswer, isDisplayOnly } = props; + const { question, showAnswer, handleOnSubmitAnswer, students, passedAnswer, showResults } = props; const [pickRates, setPickRates] = useState<{ trueRate: number, falseRate: number, trueCount: number, falseCount: number, totalCount: number }>({ trueRate: 0, falseRate: 0, @@ -25,7 +25,6 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { falseCount: 0, totalCount: 0 }); - const [showCorrectAnswers, setShowCorrectAnswers] = useState(false); const [answer, setAnswer] = useState(() => { @@ -61,10 +60,6 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { const selectedTrue = answer ? 'selected' : ''; const selectedFalse = answer !== undefined && !answer ? 'selected' : ''; - const toggleShowCorrectAnswers = () => { - setShowCorrectAnswers(!showCorrectAnswers); - }; - // Calcul le pick rate de chaque réponse const calculatePickRates = () => { if (!students) { @@ -75,12 +70,14 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { const totalAnswers = students.length; const trueAnswers = students.filter(student => student.answers.some(ans => - ans.idQuestion === Number(question.id) && ans.answer === true - )).length; + ans.idQuestion === Number(question.id) && ans.answer.some(a => a === true) + ) + ).length; const falseAnswers = students.filter(student => student.answers.some(ans => - ans.idQuestion === Number(question.id) && ans.answer === false - )).length; + ans.idQuestion === Number(question.id) && ans.answer.some(a => a === false) + ) + ).length; setPickRates({ trueRate: (trueAnswers / totalAnswers) * 100, @@ -92,99 +89,91 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { }; return ( -
-
-
-
-
- + + + +
+ {question.formattedGlobalFeedback && showAnswer && ( +
+
)} - - )} - - {showAnswer && !answer && question.falseFormattedFeedback && ( -
-
-
- )} - - - +
- {question.formattedGlobalFeedback && showAnswer && ( -
-
-
- )} - {!showAnswer && handleOnSubmitAnswer && ( - - )} - - {isDisplayOnly && ( -
- -
- )}
); }; diff --git a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx index 901e133..0d9e59f 100644 --- a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx +++ b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx @@ -18,7 +18,7 @@ import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton'; import QuestionDisplay from 'src/components/QuestionsDisplay/QuestionDisplay'; import ApiService from '../../../services/ApiService'; import { QuestionType } from 'src/Types/QuestionType'; -import { Button } from '@mui/material'; +import { Button, FormControlLabel, Switch } from '@mui/material'; import { checkIfIsCorrect } from './useRooms'; const ManageRoom: React.FC = () => { @@ -34,6 +34,7 @@ const ManageRoom: React.FC = () => { const [quizStarted, setQuizStarted] = useState(false); const [formattedRoomName, setFormattedRoomName] = useState(""); const [newlyConnectedUser, setNewlyConnectedUser] = useState(null); + const [showResults, setShowResults] = useState(false); // Handle the newly connected user in useEffect, because it needs state info // not available in the socket.on() callback @@ -407,7 +408,17 @@ const ManageRoom: React.FC = () => { {quizQuestions?.length} )} - + Afficher les résultats
} + control={ + ) => + setShowResults(e.target.checked) + } + /> + } + /> {quizMode === 'teacher' && (
{/* { showAnswer={false} question={currentQuestion?.question as Question} students={students} - isDisplayOnly={true} + showResults={showResults} /> )}