mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Try to use a map for results, but it's still not clean
This commit is contained in:
parent
2a2cba6415
commit
35770dd105
2 changed files with 76 additions and 40 deletions
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue