From d7b33423e8390b04b7651ef24c4431daae82bf39 Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Mon, 3 Feb 2025 13:53:40 -0500 Subject: [PATCH 1/7] =?UTF-8?q?Probl=C3=A8me=20dans=20l'affichage=20des=20?= =?UTF-8?q?r=C3=A9troactions=20=20Katek=20pour=20les=20questions=20r=C3=A9?= =?UTF-8?q?ponses=20courtes=20et=20num=C3=A9riques=20Fixes=20#220?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/QuestionsDisplay/questionStyle.css | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/components/QuestionsDisplay/questionStyle.css b/client/src/components/QuestionsDisplay/questionStyle.css index 3958e92..d731d4c 100644 --- a/client/src/components/QuestionsDisplay/questionStyle.css +++ b/client/src/components/QuestionsDisplay/questionStyle.css @@ -27,7 +27,6 @@ } .question-wrapper .katex { - display: block; text-align: center; } From 44f36a3a6bbe0d5e2c06339395f796bf9d617ef8 Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Mon, 3 Feb 2025 15:47:05 -0500 Subject: [PATCH 2/7] =?UTF-8?q?Probl=C3=A8me=20dans=20l'affichage=20des=20?= =?UTF-8?q?r=C3=A9troactions=20=20Katek=20pour=20les=20pr=C3=A9visualisati?= =?UTF-8?q?ons=20(=C3=89diteur=20de=20quiz)=20Fixes=20#221?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/QuestionsDisplay/questionStyle.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/QuestionsDisplay/questionStyle.css b/client/src/components/QuestionsDisplay/questionStyle.css index 3958e92..8bbe92c 100644 --- a/client/src/components/QuestionsDisplay/questionStyle.css +++ b/client/src/components/QuestionsDisplay/questionStyle.css @@ -120,9 +120,9 @@ } .feedback-container { - margin-left: 1.1rem; - display: inline-flex !important; /* override the parent */ + display: inline-block !important; /* override the parent */ align-items: center; + margin-left: 1.1rem; position: relative; padding: 0 0.5rem; background-color: hsl(43, 100%, 94%); From 8edc77d21729a08c34df77947ac6ee1f7336c231 Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Tue, 4 Feb 2025 20:21:32 -0500 Subject: [PATCH 3/7] =?UTF-8?q?[Katex]=20La=20L'affichage=20du=20tableau?= =?UTF-8?q?=20AVEC=20r=C3=A9ponses=20pose=20probl=C3=A8me=20lorsqu'il=20y?= =?UTF-8?q?=20a=20des=20=C3=A9quations=20Fixes=20#226?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LiveResults/LiveResults.test.tsx | 163 ++++++++++++++++++ .../components/LiveResults/LiveResults.tsx | 2 +- 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 client/src/__tests__/components/LiveResults/LiveResults.test.tsx diff --git a/client/src/__tests__/components/LiveResults/LiveResults.test.tsx b/client/src/__tests__/components/LiveResults/LiveResults.test.tsx new file mode 100644 index 0000000..ce6244e --- /dev/null +++ b/client/src/__tests__/components/LiveResults/LiveResults.test.tsx @@ -0,0 +1,163 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import LiveResults from 'src/components/LiveResults/LiveResults'; +import { QuestionType } from 'src/Types/QuestionType'; +import { StudentType } from 'src/Types/StudentType'; +import { Socket } from 'socket.io-client'; +import { BaseQuestion,parse } from 'gift-pegjs'; + +const mockSocket: Socket = { + on: jest.fn(), + off: jest.fn(), + emit: jest.fn(), + connect: jest.fn(), + disconnect: jest.fn(), +} as unknown as Socket; + +const mockGiftQuestions = parse( + `::Sample Question 1:: Question stem + { + =Choice 1 + ~Choice 2 + }`); + +const mockQuestions: QuestionType[] = mockGiftQuestions.map((question, index) => { + if (question.type !== "Category") + question.id = (index + 1).toString(); + const newMockQuestion = question; + return {question : newMockQuestion as BaseQuestion}; +}); + +const mockStudents: StudentType[] = [ + { id: '1', name: 'Student 1', answers: [{ idQuestion: 1, answer: 'Choice 1', isCorrect: true }] }, + { id: '2', name: 'Student 2', answers: [{ idQuestion: 1, answer: 'Choice 2', isCorrect: false }] }, +]; + +describe('LiveResults', () => { + test('renders the component with questions and students', () => { + render( + + ); + expect(screen.getByText(`Q${1}`)).toBeInTheDocument(); + + // Toggle the display of usernames + const toggleUsernamesSwitch = screen.getByLabelText('Afficher les noms'); + + // Toggle the display of usernames back + fireEvent.click(toggleUsernamesSwitch); + + // Check if the component renders the students + mockStudents.forEach((student) => { + expect(screen.getByText(student.name)).toBeInTheDocument(); + }); + }); + + test('toggles the display of usernames', () => { + render( + + ); + + // Toggle the display of usernames + const toggleUsernamesSwitch = screen.getByLabelText('Afficher les noms'); + + // Toggle the display of usernames back + fireEvent.click(toggleUsernamesSwitch); + + // Check if the usernames are shown again + mockStudents.forEach((student) => { + expect(screen.getByText(student.name)).toBeInTheDocument(); + }); + }); + +}); +test('calculates and displays the correct student grades', () => { + render( + + ); + + + // Toggle the display of usernames + const toggleUsernamesSwitch = screen.getByLabelText('Afficher les noms'); + + // Toggle the display of usernames back + fireEvent.click(toggleUsernamesSwitch); + + // Check if the student grades are calculated and displayed correctly + mockStudents.forEach((student) => { + const grade = student.answers.filter(answer => answer.isCorrect).length / mockQuestions.length * 100; + expect(screen.getByText(`${grade.toFixed()} %`)).toBeInTheDocument(); + }); +}); + +test('calculates and displays the class average', () => { + render( + + ); + + // Toggle the display of usernames + const toggleUsernamesSwitch = screen.getByLabelText('Afficher les noms'); + + // Toggle the display of usernames back + fireEvent.click(toggleUsernamesSwitch); + + // Calculate the class average + const totalGrades = mockStudents.reduce((total, student) => { + return total + (student.answers.filter(answer => answer.isCorrect).length / mockQuestions.length * 100); + }, 0); + const classAverage = totalGrades / mockStudents.length; + + // Check if the class average is displayed correctly + const classAverageElements = screen.getAllByText(`${classAverage.toFixed()} %`); + const classAverageElement = classAverageElements.find((element) => { + return element.closest('td')?.classList.contains('MuiTableCell-footer'); + }); + expect(classAverageElement).toBeInTheDocument(); +}); + +test('displays the correct answers per question', () => { + render( + + ); + + // Check if the correct answers per question are displayed correctly + mockQuestions.forEach((_, index) => { + const correctAnswers = mockStudents.filter(student => student.answers.some(answer => answer.idQuestion === index + 1 && answer.isCorrect)).length; + const correctAnswersPercentage = (correctAnswers / mockStudents.length) * 100; + const correctAnswersElements = screen.getAllByText(`${correctAnswersPercentage.toFixed()} %`); + const correctAnswersElement = correctAnswersElements.find((element) => { + return element.closest('td')?.classList.contains('MuiTableCell-root'); + }); + expect(correctAnswersElement).toBeInTheDocument(); + }); +}); \ No newline at end of file diff --git a/client/src/components/LiveResults/LiveResults.tsx b/client/src/components/LiveResults/LiveResults.tsx index 6bcd7ce..4784750 100644 --- a/client/src/components/LiveResults/LiveResults.tsx +++ b/client/src/components/LiveResults/LiveResults.tsx @@ -370,7 +370,7 @@ const LiveResults: React.FC = ({ questions, showSelectedQuesti } > {showCorrectAnswers ? ( - {formatLatex(answerText)} + ) : isCorrect ? ( ) : ( From 705b0f1ddb425e0d9ba809703172d6cce2770c3e Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Wed, 5 Feb 2025 10:29:36 -0500 Subject: [PATCH 4/7] =?UTF-8?q?[Katex]=20La=20L'affichage=20du=20tableau?= =?UTF-8?q?=20AVEC=20r=C3=A9ponses=20pose=20probl=C3=A8me=20lorsqu'il=20y?= =?UTF-8?q?=20a=20des=20=C3=A9quations=20Fixes=20#226?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/LiveResults/LiveResults.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/components/LiveResults/LiveResults.tsx b/client/src/components/LiveResults/LiveResults.tsx index 4784750..4825142 100644 --- a/client/src/components/LiveResults/LiveResults.tsx +++ b/client/src/components/LiveResults/LiveResults.tsx @@ -4,6 +4,7 @@ import { Socket } from 'socket.io-client'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCheck, faCircleXmark } from '@fortawesome/free-solid-svg-icons'; import { QuestionType } from '../../Types/QuestionType'; +import DOMPurify from 'dompurify'; import './liveResult.css'; import { @@ -370,7 +371,7 @@ const LiveResults: React.FC = ({ questions, showSelectedQuesti } > {showCorrectAnswers ? ( - + ) : isCorrect ? ( ) : ( From fc623582e00cb10cef99ccde534fead19f2aad6a Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Wed, 5 Feb 2025 19:45:55 -0500 Subject: [PATCH 5/7] =?UTF-8?q?[Rythme=20enseignant]=20Fen=C3=AAtre=20de?= =?UTF-8?q?=20r=C3=A9troaction=20reste=20ouverte=20pour=20les=20prochaines?= =?UTF-8?q?=20questions=20si=20l'=C3=A9tudiant=20ne=20l'enl=C3=A8ve=20pas?= =?UTF-8?q?=20Fixes=20#222?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx b/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx index ae2d382..dea9af3 100644 --- a/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx +++ b/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx @@ -26,8 +26,11 @@ const TeacherModeQuiz: React.FC = ({ const [feedbackMessage, setFeedbackMessage] = useState(''); useEffect(() => { + // Close the feedback dialog when the question changes + handleFeedbackDialogClose(); setIsAnswerSubmitted(false); - }, [questionInfos]); + + }, [questionInfos.question]); const handleOnSubmitAnswer = (answer: string | number | boolean) => { const idQuestion = Number(questionInfos.question.id) || -1; From a539284813e8a54fb2958f9ac195758e76725ad9 Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:52:53 -0500 Subject: [PATCH 6/7] =?UTF-8?q?[Katex]=20La=20L'affichage=20du=20tableau?= =?UTF-8?q?=20AVEC=20r=C3=A9ponses=20pose=20probl=C3=A8me=20lorsqu'il=20y?= =?UTF-8?q?=20a=20des=20=C3=A9quations=20Fixes=20#226?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/LiveResults/LiveResults.tsx | 188 +----------------- 1 file changed, 2 insertions(+), 186 deletions(-) diff --git a/client/src/components/LiveResults/LiveResults.tsx b/client/src/components/LiveResults/LiveResults.tsx index 4825142..d1e560a 100644 --- a/client/src/components/LiveResults/LiveResults.tsx +++ b/client/src/components/LiveResults/LiveResults.tsx @@ -4,7 +4,6 @@ import { Socket } from 'socket.io-client'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCheck, faCircleXmark } from '@fortawesome/free-solid-svg-icons'; import { QuestionType } from '../../Types/QuestionType'; -import DOMPurify from 'dompurify'; import './liveResult.css'; import { @@ -21,7 +20,7 @@ import { TableRow } from '@mui/material'; import { StudentType } from '../../Types/StudentType'; -import { formatLatex } from '../GiftTemplate/templates/TextTypeTemplate'; +import { FormattedTextTemplate } from '../GiftTemplate/templates/TextTypeTemplate'; interface LiveResultsProps { socket: Socket | null; @@ -31,117 +30,13 @@ interface LiveResultsProps { students: StudentType[] } -// interface Answer { -// answer: string | number | boolean; -// isCorrect: boolean; -// idQuestion: number; -// } - -// interface StudentResult { -// username: string; -// idUser: string; -// answers: Answer[]; -// } const LiveResults: React.FC = ({ questions, showSelectedQuestion, students }) => { const [showUsernames, setShowUsernames] = useState(false); const [showCorrectAnswers, setShowCorrectAnswers] = useState(false); - // const [students, setStudents] = useState(initialStudents); - // const [studentResultsMap, setStudentResultsMap] = useState>(new Map()); const maxQuestions = questions.length; - // useEffect(() => { - // // Initialize the map with the current students - // const newStudentResultsMap = new Map(); - - // for (const student of students) { - // newStudentResultsMap.set(student.id, { username: student.name, idUser: student.id, answers: [] }); - // } - - // setStudentResultsMap(newStudentResultsMap); - // }, []) - - // update when students change - // useEffect(() => { - // // studentResultsMap is inconsistent with students -- need to update - - // for (const student of students as StudentType[]) { - // } - - // }, [students]) - - // useEffect(() => { - // if (socket) { - // const submitAnswerHandler = ({ - // idUser, - // answer, - // idQuestion - // }: { - // idUser: string; - // username: string; - // answer: string | number | boolean; - // idQuestion: number; - // }) => { - // console.log(`Received answer from ${idUser} for question ${idQuestion}: ${answer}`); - - // // print the list of current student names - // console.log('Current students:'); - // students.forEach((student) => { - // console.log(student.name); - // }); - - // // Update the students state using the functional form of setStudents - // setStudents((prevStudents) => { - // let foundStudent = false; - // const updatedStudents = prevStudents.map((student) => { - // if (student.id === idUser) { - // foundStudent = true; - // const updatedAnswers = student.answers.map((ans) => { - // const newAnswer: Answer = { answer, isCorrect: checkIfIsCorrect(answer, idQuestion), idQuestion }; - // console.log(`Updating answer for ${student.name} for question ${idQuestion} to ${answer}`); - // return (ans.idQuestion === idQuestion ? { ...ans, newAnswer } : ans); - // } - // ); - // return { ...student, answers: updatedAnswers }; - // } - // return student; - // }); - // if (!foundStudent) { - // console.log(`Student ${idUser} not found in the list of students in LiveResults`); - // } - // return updatedStudents; - // }); - - - // // make a copy of the students array so we can update it - // // const updatedStudents = [...students]; - - // // const student = updatedStudents.find((student) => student.id === idUser); - // // if (!student) { - // // // this is a bad thing if an answer was submitted but the student isn't in the list - // // console.log(`Student ${idUser} not found in the list of students in LiveResults`); - // // return; - // // } - - // // const isCorrect = checkIfIsCorrect(answer, idQuestion); - // // const newAnswer: Answer = { answer, isCorrect, idQuestion }; - // // student.answers.push(newAnswer); - // // // print list of answers - // // console.log('Answers:'); - // // student.answers.forEach((answer) => { - // // console.log(answer.answer); - // // }); - // // setStudents(updatedStudents); // update the state - // }; - - // socket.on('submit-answer', submitAnswerHandler); - // return () => { - // socket.off('submit-answer'); - // }; - // } - // }, [socket]); - const getStudentGrade = (student: StudentType): number => { if (student.answers.length === 0) { return 0; @@ -186,85 +81,6 @@ const LiveResults: React.FC = ({ questions, showSelectedQuesti ); }; - // (studentResults.filter((student) => - // student.answers.some( - // (answer) => - // parseInt(answer.idQuestion.toString()) === index + 1 && answer.isCorrect - // ) - // ).length / - // studentResults.length) * - // 100 - // ); - // }; - - // function checkIfIsCorrect(answer: string | number | boolean, idQuestion: number): boolean { - // const questionInfo = questions.find((q) => - // q.question.id ? q.question.id === idQuestion.toString() : false - // ) as QuestionType | undefined; - - // const answerText = answer.toString(); - // if (questionInfo) { - // const question = questionInfo.question as GIFTQuestion; - // if (question.type === 'TF') { - // return ( - // (question.isTrue && answerText == 'true') || - // (!question.isTrue && answerText == 'false') - // ); - // } else if (question.type === 'MC') { - // return question.choices.some( - // (choice) => choice.isCorrect && choice.text.text === answerText - // ); - // } else if (question.type === 'Numerical') { - // if (question.choices && !Array.isArray(question.choices)) { - // if ( - // question.choices.type === 'high-low' && - // question.choices.numberHigh && - // question.choices.numberLow - // ) { - // const answerNumber = parseFloat(answerText); - // if (!isNaN(answerNumber)) { - // return ( - // answerNumber <= question.choices.numberHigh && - // answerNumber >= question.choices.numberLow - // ); - // } - // } - // } - // if (question.choices && Array.isArray(question.choices)) { - // if ( - // question.choices[0].text.type === 'range' && - // question.choices[0].text.number && - // question.choices[0].text.range - // ) { - // const answerNumber = parseFloat(answerText); - // const range = question.choices[0].text.range; - // const correctAnswer = question.choices[0].text.number; - // if (!isNaN(answerNumber)) { - // return ( - // answerNumber <= correctAnswer + range && - // answerNumber >= correctAnswer - range - // ); - // } - // } - // if ( - // question.choices[0].text.type === 'simple' && - // question.choices[0].text.number - // ) { - // const answerNumber = parseFloat(answerText); - // if (!isNaN(answerNumber)) { - // return answerNumber === question.choices[0].text.number; - // } - // } - // } - // } else if (question.type === 'Short') { - // return question.choices.some( - // (choice) => choice.text.text.toUpperCase() === answerText.toUpperCase() - // ); - // } - // } - // return false; - // } - return ( @@ -371,7 +187,7 @@ const LiveResults: React.FC = ({ questions, showSelectedQuesti } > {showCorrectAnswers ? ( - + ) : isCorrect ? ( ) : ( From c396b60734f395665a44086bdd2c50c7e7793413 Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:09:17 -0500 Subject: [PATCH 7/7] Faire l'appel de TextTypeTemplate au lieu de format() et sanitize() Fixes #233 --- .../GiftTemplate/GIFTTemplatePreview.tsx | 4 +- .../templates/TextTypeTemplate.ts | 2 +- .../components/LiveResults/LiveResults.tsx | 187 +----------------- 3 files changed, 5 insertions(+), 188 deletions(-) diff --git a/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx b/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx index 51dbd3f..f4ab035 100644 --- a/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx +++ b/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react'; import Template, { ErrorTemplate } from './templates'; import { parse } from 'gift-pegjs'; import './styles.css'; -import DOMPurify from 'dompurify'; +import { FormattedTextTemplate } from './templates/TextTypeTemplate'; interface GIFTTemplatePreviewProps { questions: string[]; @@ -74,7 +74,7 @@ const GIFTTemplatePreview: React.FC = ({ {error} ) : isPreviewReady ? ( - + ) : ( Chargement de la prévisualisation... diff --git a/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts b/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts index 8a3e24b..c86b25e 100644 --- a/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts +++ b/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts @@ -4,7 +4,7 @@ import katex from 'katex'; import { TextFormat } from 'gift-pegjs'; import DOMPurify from 'dompurify'; // cleans HTML to prevent XSS attacks, etc. -export function formatLatex(text: string): string { +function formatLatex(text: string): string { return text .replace(/\$\$(.*?)\$\$/g, (_, inner) => katex.renderToString(inner, { displayMode: true })) .replace(/\$(.*?)\$/g, (_, inner) => katex.renderToString(inner, { displayMode: false })) diff --git a/client/src/components/LiveResults/LiveResults.tsx b/client/src/components/LiveResults/LiveResults.tsx index 6bcd7ce..d1e560a 100644 --- a/client/src/components/LiveResults/LiveResults.tsx +++ b/client/src/components/LiveResults/LiveResults.tsx @@ -20,7 +20,7 @@ import { TableRow } from '@mui/material'; import { StudentType } from '../../Types/StudentType'; -import { formatLatex } from '../GiftTemplate/templates/TextTypeTemplate'; +import { FormattedTextTemplate } from '../GiftTemplate/templates/TextTypeTemplate'; interface LiveResultsProps { socket: Socket | null; @@ -30,117 +30,13 @@ interface LiveResultsProps { students: StudentType[] } -// interface Answer { -// answer: string | number | boolean; -// isCorrect: boolean; -// idQuestion: number; -// } - -// interface StudentResult { -// username: string; -// idUser: string; -// answers: Answer[]; -// } const LiveResults: React.FC = ({ questions, showSelectedQuestion, students }) => { const [showUsernames, setShowUsernames] = useState(false); const [showCorrectAnswers, setShowCorrectAnswers] = useState(false); - // const [students, setStudents] = useState(initialStudents); - // const [studentResultsMap, setStudentResultsMap] = useState>(new Map()); const maxQuestions = questions.length; - // useEffect(() => { - // // Initialize the map with the current students - // const newStudentResultsMap = new Map(); - - // for (const student of students) { - // newStudentResultsMap.set(student.id, { username: student.name, idUser: student.id, answers: [] }); - // } - - // setStudentResultsMap(newStudentResultsMap); - // }, []) - - // update when students change - // useEffect(() => { - // // studentResultsMap is inconsistent with students -- need to update - - // for (const student of students as StudentType[]) { - // } - - // }, [students]) - - // useEffect(() => { - // if (socket) { - // const submitAnswerHandler = ({ - // idUser, - // answer, - // idQuestion - // }: { - // idUser: string; - // username: string; - // answer: string | number | boolean; - // idQuestion: number; - // }) => { - // console.log(`Received answer from ${idUser} for question ${idQuestion}: ${answer}`); - - // // print the list of current student names - // console.log('Current students:'); - // students.forEach((student) => { - // console.log(student.name); - // }); - - // // Update the students state using the functional form of setStudents - // setStudents((prevStudents) => { - // let foundStudent = false; - // const updatedStudents = prevStudents.map((student) => { - // if (student.id === idUser) { - // foundStudent = true; - // const updatedAnswers = student.answers.map((ans) => { - // const newAnswer: Answer = { answer, isCorrect: checkIfIsCorrect(answer, idQuestion), idQuestion }; - // console.log(`Updating answer for ${student.name} for question ${idQuestion} to ${answer}`); - // return (ans.idQuestion === idQuestion ? { ...ans, newAnswer } : ans); - // } - // ); - // return { ...student, answers: updatedAnswers }; - // } - // return student; - // }); - // if (!foundStudent) { - // console.log(`Student ${idUser} not found in the list of students in LiveResults`); - // } - // return updatedStudents; - // }); - - - // // make a copy of the students array so we can update it - // // const updatedStudents = [...students]; - - // // const student = updatedStudents.find((student) => student.id === idUser); - // // if (!student) { - // // // this is a bad thing if an answer was submitted but the student isn't in the list - // // console.log(`Student ${idUser} not found in the list of students in LiveResults`); - // // return; - // // } - - // // const isCorrect = checkIfIsCorrect(answer, idQuestion); - // // const newAnswer: Answer = { answer, isCorrect, idQuestion }; - // // student.answers.push(newAnswer); - // // // print list of answers - // // console.log('Answers:'); - // // student.answers.forEach((answer) => { - // // console.log(answer.answer); - // // }); - // // setStudents(updatedStudents); // update the state - // }; - - // socket.on('submit-answer', submitAnswerHandler); - // return () => { - // socket.off('submit-answer'); - // }; - // } - // }, [socket]); - const getStudentGrade = (student: StudentType): number => { if (student.answers.length === 0) { return 0; @@ -185,85 +81,6 @@ const LiveResults: React.FC = ({ questions, showSelectedQuesti ); }; - // (studentResults.filter((student) => - // student.answers.some( - // (answer) => - // parseInt(answer.idQuestion.toString()) === index + 1 && answer.isCorrect - // ) - // ).length / - // studentResults.length) * - // 100 - // ); - // }; - - // function checkIfIsCorrect(answer: string | number | boolean, idQuestion: number): boolean { - // const questionInfo = questions.find((q) => - // q.question.id ? q.question.id === idQuestion.toString() : false - // ) as QuestionType | undefined; - - // const answerText = answer.toString(); - // if (questionInfo) { - // const question = questionInfo.question as GIFTQuestion; - // if (question.type === 'TF') { - // return ( - // (question.isTrue && answerText == 'true') || - // (!question.isTrue && answerText == 'false') - // ); - // } else if (question.type === 'MC') { - // return question.choices.some( - // (choice) => choice.isCorrect && choice.text.text === answerText - // ); - // } else if (question.type === 'Numerical') { - // if (question.choices && !Array.isArray(question.choices)) { - // if ( - // question.choices.type === 'high-low' && - // question.choices.numberHigh && - // question.choices.numberLow - // ) { - // const answerNumber = parseFloat(answerText); - // if (!isNaN(answerNumber)) { - // return ( - // answerNumber <= question.choices.numberHigh && - // answerNumber >= question.choices.numberLow - // ); - // } - // } - // } - // if (question.choices && Array.isArray(question.choices)) { - // if ( - // question.choices[0].text.type === 'range' && - // question.choices[0].text.number && - // question.choices[0].text.range - // ) { - // const answerNumber = parseFloat(answerText); - // const range = question.choices[0].text.range; - // const correctAnswer = question.choices[0].text.number; - // if (!isNaN(answerNumber)) { - // return ( - // answerNumber <= correctAnswer + range && - // answerNumber >= correctAnswer - range - // ); - // } - // } - // if ( - // question.choices[0].text.type === 'simple' && - // question.choices[0].text.number - // ) { - // const answerNumber = parseFloat(answerText); - // if (!isNaN(answerNumber)) { - // return answerNumber === question.choices[0].text.number; - // } - // } - // } - // } else if (question.type === 'Short') { - // return question.choices.some( - // (choice) => choice.text.text.toUpperCase() === answerText.toUpperCase() - // ); - // } - // } - // return false; - // } - return ( @@ -370,7 +187,7 @@ const LiveResults: React.FC = ({ questions, showSelectedQuesti } > {showCorrectAnswers ? ( - {formatLatex(answerText)} + ) : isCorrect ? ( ) : (