Try to use a map for results, but it's still not clean

This commit is contained in:
C. Fuhrman 2024-09-25 11:17:06 -04:00
parent 2a2cba6415
commit 35770dd105
2 changed files with 76 additions and 40 deletions

View file

@ -45,27 +45,37 @@ interface StudentResult {
const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelectedQuestion, students }) => { const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelectedQuestion, students }) => {
const [showUsernames, setShowUsernames] = useState<boolean>(false); const [showUsernames, setShowUsernames] = useState<boolean>(false);
const [showCorrectAnswers, setShowCorrectAnswers] = useState<boolean>(false); const [showCorrectAnswers, setShowCorrectAnswers] = useState<boolean>(false);
const [studentResults, setStudentResults] = useState<StudentResult[]>([]); const [studentResultsMap, setStudentResultsMap] = useState<Map<string, StudentResult>>(new Map());
const maxQuestions = questions.length; const maxQuestions = questions.length;
useEffect(() => { useEffect(() => {
// Set student list before starting // Initialize the map with the current students
let newStudents: StudentResult[] = []; const newStudentResultsMap = new Map<string, StudentResult>();
for (const student of students as UserType[]) { for (const student of students) {
newStudents.push({ username: student.name, idUser: student.id, answers: [] }) newStudentResultsMap.set(student.id, { username: student.name, idUser: student.id, answers: [] });
} }
setStudentResults(newStudents); setStudentResultsMap(newStudentResultsMap);
}, []) }, [])
// update when students change
useEffect(() => {
// studentResultsMap is inconsistent with students -- need to update
for (const student of students as UserType[]) {
if (!studentResultsMap.has(student.id)) {
studentResultsMap.set(student.id, { username: student.name, idUser: student.id, answers: [] });
}
}
}, [students])
useEffect(() => { useEffect(() => {
if (socket) { if (socket) {
const submitAnswerHandler = ({ const submitAnswerHandler = ({
idUser, idUser,
username,
answer, answer,
idQuestion idQuestion
}: { }: {
@ -74,22 +84,35 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
answer: string | number | boolean; answer: string | number | boolean;
idQuestion: number; idQuestion: number;
}) => { }) => {
setStudentResults((currentResults) => { // Update the student results in the map with the answer
const userIndex = currentResults.findIndex( setStudentResultsMap((currentResults) => {
(result) => result.idUser === idUser const studentResult = currentResults.get(idUser);
); if (!studentResult) {
const isCorrect = checkIfIsCorrect(answer, idQuestion); return currentResults;
if (userIndex !== -1) {
const newResults = [...currentResults];
newResults[userIndex].answers.push({ answer, isCorrect, idQuestion });
return newResults;
} else {
return [
...currentResults,
{ idUser, username, answers: [{ answer, isCorrect, idQuestion }] }
];
} }
const isCorrect = checkIfIsCorrect(answer, idQuestion);
studentResult.answers.push({ answer, isCorrect, idQuestion });
return new Map(currentResults).set(idUser, studentResult);
}); });
// setStudentResults((currentResults) => {
// const userIndex = currentResults.findIndex(
// (result) => result.idUser === idUser
// );
// const isCorrect = checkIfIsCorrect(answer, idQuestion);
// if (userIndex !== -1) {
// const newResults = [...currentResults];
// newResults[userIndex].answers.push({ answer, isCorrect, idQuestion });
// return newResults;
// } else {
// return [
// ...currentResults,
// { idUser, username, answers: [{ answer, isCorrect, idQuestion }] }
// ];
// }
// });
}; };
socket.on('submit-answer', submitAnswerHandler); socket.on('submit-answer', submitAnswerHandler);
@ -124,26 +147,39 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
const classAverage: number = useMemo(() => { const classAverage: number = useMemo(() => {
let classTotal = 0; let classTotal = 0;
const studentResults = Array.from(studentResultsMap.values());
studentResults.forEach((student) => { studentResults.forEach((student) => {
classTotal += getStudentGrade(student); classTotal += getStudentGrade(student);
}); });
return classTotal / studentResults.length; return classTotal / studentResults.length;
}, [studentResults]); }, [studentResultsMap]);
const getCorrectAnswersPerQuestion = (index: number): number => { const getCorrectAnswersPerQuestion = (index: number): number => {
return ( return (
(studentResults.filter((student) => (Array.from(studentResultsMap.values()).filter((student) =>
student.answers.some( student.answers.some(
(answer) => (answer) =>
parseInt(answer.idQuestion.toString()) === index + 1 && answer.isCorrect parseInt(answer.idQuestion.toString()) === index + 1 && answer.isCorrect
) )
).length / ).length / studentResultsMap.size) *
studentResults.length) *
100 100
); );
}; };
// (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 { function checkIfIsCorrect(answer: string | number | boolean, idQuestion: number): boolean {
const questionInfo = questions.find((q) => const questionInfo = questions.find((q) =>
q.question.id ? q.question.id === idQuestion.toString() : false q.question.id ? q.question.id === idQuestion.toString() : false
@ -278,7 +314,7 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{studentResults.map((student) => ( {Array.from(studentResultsMap.values()).map((student) => (
<TableRow key={student.idUser}> <TableRow key={student.idUser}>
<TableCell <TableCell
className="sticky-column" className="sticky-column"
@ -360,7 +396,7 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
color: 'rgba(0, 0, 0)' color: 'rgba(0, 0, 0)'
}} }}
> >
{studentResults.length > 0 {studentResultsMap.size > 0
? `${getCorrectAnswersPerQuestion(index).toFixed()} %` ? `${getCorrectAnswersPerQuestion(index).toFixed()} %`
: '-'} : '-'}
</TableCell> </TableCell>
@ -376,7 +412,7 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
color: 'rgba(0, 0, 0)' color: 'rgba(0, 0, 0)'
}} }}
> >
{studentResults.length > 0 ? `${classAverage.toFixed()} %` : '-'} {studentResultsMap.size > 0 ? `${classAverage.toFixed()} %` : '-'}
</TableCell> </TableCell>
</TableRow> </TableRow>
</TableFooter> </TableFooter>

View file

@ -25,7 +25,7 @@ const ManageRoom: React.FC = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [roomName, setRoomName] = useState<string>(''); const [roomName, setRoomName] = useState<string>('');
const [socket, setSocket] = useState<Socket | null>(null); const [socket, setSocket] = useState<Socket | null>(null);
const [users, setUsers] = useState<UserType[]>([]); const [students, setStudents] = useState<UserType[]>([]);
const quizId = useParams<{ id: string }>(); const quizId = useParams<{ id: string }>();
const [quizQuestions, setQuizQuestions] = useState<QuestionType[] | undefined>(); const [quizQuestions, setQuizQuestions] = useState<QuestionType[] | undefined>();
const [quiz, setQuiz] = useState<QuizType | null>(null); const [quiz, setQuiz] = useState<QuizType | null>(null);
@ -74,7 +74,7 @@ const ManageRoom: React.FC = () => {
setSocket(null); setSocket(null);
setQuizQuestions(undefined); setQuizQuestions(undefined);
setCurrentQuestion(undefined); setCurrentQuestion(undefined);
setUsers([]); setStudents([]);
setRoomName(''); setRoomName('');
} }
}; };
@ -96,9 +96,9 @@ const ManageRoom: React.FC = () => {
socket.on('create-failure', () => { socket.on('create-failure', () => {
console.log('Error creating room.'); console.log('Error creating room.');
}); });
socket.on('user-joined', (user: UserType) => { socket.on('user-joined', (student: UserType) => {
setUsers((prevUsers) => [...prevUsers, user]); setStudents((prevStudents) => [...prevStudents, student]);
if (quizMode === 'teacher') { if (quizMode === 'teacher') {
webSocketService.nextQuestion(roomName, currentQuestion); webSocketService.nextQuestion(roomName, currentQuestion);
@ -111,7 +111,7 @@ const ManageRoom: React.FC = () => {
setSocket(null); setSocket(null);
}); });
socket.on('user-disconnected', (userId: string) => { socket.on('user-disconnected', (userId: string) => {
setUsers((prevUsers) => prevUsers.filter((user) => user.id !== userId)); setStudents((prevUsers) => prevUsers.filter((user) => user.id !== userId));
}); });
setSocket(socket); setSocket(socket);
}; };
@ -119,9 +119,9 @@ const ManageRoom: React.FC = () => {
useEffect(() => { useEffect(() => {
// This is here to make sure the correct value is sent when user join // This is here to make sure the correct value is sent when user join
if (socket) { if (socket) {
socket.on('user-joined', (user: UserType) => { socket.on('user-joined', (_student: UserType) => {
setUsers((prevUsers) => [...prevUsers, user]); // setUsers((prevUsers) => [...prevUsers, user]);
if (quizMode === 'teacher') { if (quizMode === 'teacher') {
webSocketService.nextQuestion(roomName, currentQuestion); webSocketService.nextQuestion(roomName, currentQuestion);
@ -250,13 +250,13 @@ const ManageRoom: React.FC = () => {
<div className='centerTitle'> <div className='centerTitle'>
<div className='title'>Salle: {roomName}</div> <div className='title'>Salle: {roomName}</div>
<div className='userCount subtitle'>Utilisateurs: {users.length}/60</div> <div className='userCount subtitle'>Utilisateurs: {students.length}/60</div>
</div> </div>
<div className='dumb'></div> <div className='dumb'></div>
</div> </div>
{/* the following breaks the css (nested room classes) */} {/* the following breaks the css (if 'room' classes are nested) */}
<div className=''> <div className=''>
{quizQuestions ? ( {quizQuestions ? (
@ -293,7 +293,7 @@ const ManageRoom: React.FC = () => {
socket={socket} socket={socket}
questions={quizQuestions} questions={quizQuestions}
showSelectedQuestion={showSelectedQuestion} showSelectedQuestion={showSelectedQuestion}
students={users} students={students}
></LiveResultsComponent> ></LiveResultsComponent>
</div> </div>
@ -312,7 +312,7 @@ const ManageRoom: React.FC = () => {
) : ( ) : (
<UserWaitPage <UserWaitPage
users={users} users={students}
launchQuiz={launchQuiz} launchQuiz={launchQuiz}
setQuizMode={setQuizMode} setQuizMode={setQuizMode}
/> />