mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Merge 7b83a93c5b into ee7a7a0544
This commit is contained in:
commit
dc5f6bc8b0
6 changed files with 333 additions and 306 deletions
|
|
@ -3,93 +3,274 @@ 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 { Socket } from 'socket.io-client';
|
||||
import { StudentType } from 'src/Types/StudentType';
|
||||
import { BaseQuestion, parse } from 'gift-pegjs';
|
||||
|
||||
const mockGiftQuestions = parse(
|
||||
`::Sample Question 1:: Sample Question 1 {=Answer 1 ~Answer 2}
|
||||
`::Sample Question 1:: Question stem
|
||||
{
|
||||
=Choice 1
|
||||
=Choice 2
|
||||
~Choice 3
|
||||
~Choice 4
|
||||
}
|
||||
|
||||
::Sample Question 2:: Sample Question 2 {T}`);
|
||||
::Sample Question 2:: Question stem {TRUE}
|
||||
`);
|
||||
|
||||
|
||||
const mockSocket: Socket = {
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
emit: jest.fn(),
|
||||
connect: jest.fn(),
|
||||
disconnect: jest.fn(),
|
||||
} as unknown as Socket;
|
||||
|
||||
const mockQuestions: QuestionType[] = mockGiftQuestions.map((question, index) => {
|
||||
if (question.type !== "Category")
|
||||
question.id = (index + 1).toString();
|
||||
const newMockQuestion = question;
|
||||
return {question : newMockQuestion as BaseQuestion};
|
||||
return { question: newMockQuestion as BaseQuestion };
|
||||
});
|
||||
|
||||
console.log(`mockQuestions: ${JSON.stringify(mockQuestions)}`);
|
||||
|
||||
// each student should have a different score for the tests to pass
|
||||
const mockStudents: StudentType[] = [
|
||||
{ id: "1", name: 'Student 1', answers: [{ idQuestion: 1, answer: ['Answer 1'], isCorrect: true }] },
|
||||
{ id: "2", name: 'Student 2', answers: [{ idQuestion: 2, answer: ['Answer 2'], isCorrect: false }] },
|
||||
{ id: '1', name: 'Student 1', answers: [] },
|
||||
{ id: '2', name: 'Student 2', answers: [{ idQuestion: 1, answer: ['Choice 3'], isCorrect: false }, { idQuestion: 2, answer: [true], isCorrect: true}] },
|
||||
{ id: '3', name: 'Student 3', answers: [{ idQuestion: 1, answer: ['Choice 1', 'Choice 2'], isCorrect: true }, { idQuestion: 2, answer: [true], isCorrect: true}] },
|
||||
];
|
||||
|
||||
const mockShowSelectedQuestion = jest.fn();
|
||||
|
||||
describe('LiveResults', () => {
|
||||
test('renders LiveResults component', () => {
|
||||
test('renders the component with questions and students', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText(`Q${1}`)).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Résultats du quiz')).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 show usernames switch', () => {
|
||||
test('toggles the display of usernames', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
const switchElement = screen.getByLabelText('Afficher les noms');
|
||||
expect(switchElement).toBeInTheDocument();
|
||||
// Toggle the display of usernames
|
||||
const toggleUsernamesSwitch = screen.getByLabelText('Afficher les noms');
|
||||
|
||||
fireEvent.click(switchElement);
|
||||
expect(switchElement).toBeChecked();
|
||||
// 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('toggles show correct answers switch', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
});
|
||||
test('calculates and displays the correct student grades', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
const switchElement = screen.getByLabelText('Afficher les réponses');
|
||||
expect(switchElement).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(switchElement);
|
||||
expect(switchElement).toBeChecked();
|
||||
// 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
|
||||
const getByTextInTableCellBody = (text: string) => {
|
||||
const elements = screen.getAllByText(text); // Get all elements with the specified text
|
||||
return elements.find((element) => element.closest('.MuiTableCell-body')); // don't get the footer element(s)
|
||||
};
|
||||
mockStudents.forEach((student) => {
|
||||
const grade = student.answers.filter(answer => answer.isCorrect).length / mockQuestions.length * 100;
|
||||
const element = getByTextInTableCellBody(`${grade.toFixed()} %`);
|
||||
expect(element).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('calculates and displays the class average', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
// 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('calls showSelectedQuestion when a table cell is clicked', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
test('displays the correct answers per question', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
const tableCell = screen.getByText('Q1');
|
||||
fireEvent.click(tableCell);
|
||||
|
||||
expect(mockShowSelectedQuestion).toHaveBeenCalled();
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('renders LiveResults component', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Résultats du quiz')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('toggles show usernames switch', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
const switchElement = screen.getByLabelText('Afficher les noms');
|
||||
expect(switchElement).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(switchElement);
|
||||
expect(switchElement).toBeChecked();
|
||||
});
|
||||
|
||||
test('toggles show correct answers switch', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
const switchElement = screen.getByLabelText('Afficher les réponses');
|
||||
expect(switchElement).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(switchElement);
|
||||
expect(switchElement).toBeChecked();
|
||||
});
|
||||
|
||||
test('calls showSelectedQuestion when a table cell is clicked', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
const tableCell = screen.getByText('Q1');
|
||||
fireEvent.click(tableCell);
|
||||
|
||||
expect(mockShowSelectedQuestion).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('toggles the visibility of content when the arrow button is clicked', () => {
|
||||
render(<LiveResults
|
||||
socket={null}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={mockShowSelectedQuestion}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>);
|
||||
const toggleSwitch = screen.getByTestId("liveResults-switch");
|
||||
expect(toggleSwitch).toBeInTheDocument();
|
||||
expect(screen.queryByText('Afficher les noms')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Afficher les réponses')).toBeInTheDocument();
|
||||
expect(screen.queryByTestId('table-container')).toBeInTheDocument();
|
||||
|
||||
|
||||
fireEvent.click(toggleSwitch);
|
||||
screen.debug();
|
||||
|
||||
expect(screen.queryByText('Afficher les noms')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Afficher les réponses')).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId('table-container')).not.toBeInTheDocument();
|
||||
|
||||
fireEvent.click(toggleSwitch);
|
||||
expect(screen.queryByText('Afficher les noms')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Afficher les réponses')).toBeInTheDocument();
|
||||
expect(screen.queryByTestId('table-container')).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,178 +0,0 @@
|
|||
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
|
||||
~Choice 3
|
||||
~Choice 4
|
||||
}
|
||||
|
||||
::Sample Question 2:: Question stem {TRUE}
|
||||
`);
|
||||
|
||||
const mockQuestions: QuestionType[] = mockGiftQuestions.map((question, index) => {
|
||||
if (question.type !== "Category")
|
||||
question.id = (index + 1).toString();
|
||||
const newMockQuestion = question;
|
||||
return { question: newMockQuestion as BaseQuestion };
|
||||
});
|
||||
|
||||
console.log(`mockQuestions: ${JSON.stringify(mockQuestions)}`);
|
||||
|
||||
// each student should have a different score for the tests to pass
|
||||
const mockStudents: StudentType[] = [
|
||||
{ id: '1', name: 'Student 1', answers: [] },
|
||||
{ id: '2', name: 'Student 2', answers: [{ idQuestion: 1, answer: ['Choice 3'], isCorrect: false }, { idQuestion: 2, answer: [true], isCorrect: true}] },
|
||||
{ id: '3', name: 'Student 3', answers: [{ idQuestion: 1, answer: ['Choice 1', 'Choice 2'], isCorrect: true }, { idQuestion: 2, answer: [true], isCorrect: true}] },
|
||||
];
|
||||
|
||||
describe('LiveResults', () => {
|
||||
test('renders the component with questions and students', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
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(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
// 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(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
// 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
|
||||
const getByTextInTableCellBody = (text: string) => {
|
||||
const elements = screen.getAllByText(text); // Get all elements with the specified text
|
||||
return elements.find((element) => element.closest('.MuiTableCell-body')); // don't get the footer element(s)
|
||||
};
|
||||
mockStudents.forEach((student) => {
|
||||
const grade = student.answers.filter(answer => answer.isCorrect).length / mockQuestions.length * 100;
|
||||
const element = getByTextInTableCellBody(`${grade.toFixed()} %`);
|
||||
expect(element).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('calculates and displays the class average', () => {
|
||||
render(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
// 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(
|
||||
<LiveResults
|
||||
socket={mockSocket}
|
||||
questions={mockQuestions}
|
||||
showSelectedQuestion={jest.fn()}
|
||||
quizMode="teacher"
|
||||
students={mockStudents}
|
||||
/>
|
||||
);
|
||||
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -24,49 +24,68 @@ interface LiveResultsProps {
|
|||
const LiveResults: React.FC<LiveResultsProps> = ({ questions, showSelectedQuestion, students }) => {
|
||||
const [showUsernames, setShowUsernames] = useState<boolean>(false);
|
||||
const [showCorrectAnswers, setShowCorrectAnswers] = useState<boolean>(false);
|
||||
const [isExpanded, setIsExpanded] = useState<boolean>(true);
|
||||
|
||||
const toggleExpand = () => {
|
||||
setIsExpanded(!isExpanded);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<div className="action-bar mb-1">
|
||||
<div className="text-2xl text-bold">Résultats du quiz</div>
|
||||
<FormGroup row>
|
||||
<div className="action-bar">
|
||||
<div>
|
||||
<FormControlLabel
|
||||
label={<div className="text-sm">Afficher les noms</div>}
|
||||
label={<div className="text-sm">Résultats du quiz</div>}
|
||||
control={
|
||||
<Switch
|
||||
value={showUsernames}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setShowUsernames(e.target.checked)
|
||||
}
|
||||
data-testid="liveResults-switch"
|
||||
checked={isExpanded}
|
||||
onChange={() => toggleExpand()}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormControlLabel
|
||||
label={<div className="text-sm">Afficher les réponses</div>}
|
||||
control={
|
||||
<Switch
|
||||
value={showCorrectAnswers}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setShowCorrectAnswers(e.target.checked)
|
||||
}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
{isExpanded && (
|
||||
<FormGroup row className='form-group'>
|
||||
<FormControlLabel
|
||||
label={<div className="text-sm">Afficher les noms</div>}
|
||||
control={
|
||||
<Switch
|
||||
value={showUsernames}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setShowUsernames(e.target.checked)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormControlLabel
|
||||
label={<div className="text-sm">Afficher les réponses</div>}
|
||||
control={
|
||||
<Switch
|
||||
value={showCorrectAnswers}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setShowCorrectAnswers(e.target.checked)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</div>
|
||||
{isExpanded && (
|
||||
<div className="table-container" data-testid="table-container">
|
||||
|
||||
<LiveResultsTable
|
||||
students={students}
|
||||
questions={questions}
|
||||
showCorrectAnswers={showCorrectAnswers}
|
||||
showSelectedQuestion={showSelectedQuestion}
|
||||
showUsernames={showUsernames}
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
|
||||
<LiveResultsTable
|
||||
students={students}
|
||||
questions={questions}
|
||||
showCorrectAnswers={showCorrectAnswers}
|
||||
showSelectedQuestion={showSelectedQuestion}
|
||||
showUsernames={showUsernames}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
/* Flexbox container for the action bar */
|
||||
.action-bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
/* Flexbox container for the form group */
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.table-cell-border {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const ManageRoom: React.FC = () => {
|
|||
const navigate = useNavigate();
|
||||
const [socket, setSocket] = useState<Socket | null>(null);
|
||||
const [students, setStudents] = useState<StudentType[]>([]);
|
||||
const { quizId = '', roomName = '' } = useParams<{ quizId: string, roomName: string }>();
|
||||
const { quizId = '', roomName = '' } = useParams<{ quizId: string, roomName: string }>();
|
||||
const [quizQuestions, setQuizQuestions] = useState<QuestionType[] | undefined>();
|
||||
const [quiz, setQuiz] = useState<QuizType | null>(null);
|
||||
const [quizMode, setQuizMode] = useState<'teacher' | 'student'>('teacher');
|
||||
|
|
@ -41,13 +41,13 @@ const ManageRoom: React.FC = () => {
|
|||
if (newlyConnectedUser) {
|
||||
console.log(`Handling newly connected user: ${newlyConnectedUser.name}`);
|
||||
setStudents((prevStudents) => [...prevStudents, newlyConnectedUser]);
|
||||
|
||||
|
||||
// only send nextQuestion if the quiz has started
|
||||
if (!quizStarted) {
|
||||
console.log(`!quizStarted: returning.... `);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (quizMode === 'teacher') {
|
||||
webSocketService.nextQuestion({
|
||||
roomName: formattedRoomName,
|
||||
|
|
@ -60,7 +60,7 @@ const ManageRoom: React.FC = () => {
|
|||
} else {
|
||||
console.error('Invalid quiz mode:', quizMode);
|
||||
}
|
||||
|
||||
|
||||
// Reset the newly connected user state
|
||||
setNewlyConnectedUser(null);
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ const ManageRoom: React.FC = () => {
|
|||
return () => {
|
||||
disconnectWebSocket();
|
||||
};
|
||||
}, [roomName, navigate]);
|
||||
}, [roomName, navigate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (quizId) {
|
||||
|
|
@ -213,14 +213,14 @@ const ManageRoom: React.FC = () => {
|
|||
console.log(`Comparing ${ans.idQuestion} to ${idQuestion}`);
|
||||
return ans.idQuestion === idQuestion
|
||||
? {
|
||||
...ans,
|
||||
answer,
|
||||
isCorrect: checkIfIsCorrect(
|
||||
answer,
|
||||
idQuestion,
|
||||
quizQuestions!
|
||||
)
|
||||
}
|
||||
...ans,
|
||||
answer,
|
||||
isCorrect: checkIfIsCorrect(
|
||||
answer,
|
||||
idQuestion,
|
||||
quizQuestions!
|
||||
)
|
||||
}
|
||||
: ans;
|
||||
});
|
||||
} else {
|
||||
|
|
@ -253,10 +253,12 @@ const ManageRoom: React.FC = () => {
|
|||
if (nextQuestionIndex === undefined || nextQuestionIndex > quizQuestions.length - 1) return;
|
||||
|
||||
setCurrentQuestion(quizQuestions[nextQuestionIndex]);
|
||||
webSocketService.nextQuestion({roomName: formattedRoomName,
|
||||
questions: quizQuestions,
|
||||
questionIndex: nextQuestionIndex,
|
||||
isLaunch: false});
|
||||
webSocketService.nextQuestion({
|
||||
roomName: formattedRoomName,
|
||||
questions: quizQuestions,
|
||||
questionIndex: nextQuestionIndex,
|
||||
isLaunch: false
|
||||
});
|
||||
};
|
||||
|
||||
const previousQuestion = () => {
|
||||
|
|
@ -266,7 +268,7 @@ const ManageRoom: React.FC = () => {
|
|||
|
||||
if (prevQuestionIndex === undefined || prevQuestionIndex < 0) return;
|
||||
setCurrentQuestion(quizQuestions[prevQuestionIndex]);
|
||||
webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex: prevQuestionIndex, isLaunch: false});
|
||||
webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex: prevQuestionIndex, isLaunch: false });
|
||||
};
|
||||
|
||||
const initializeQuizQuestion = () => {
|
||||
|
|
@ -294,7 +296,7 @@ const ManageRoom: React.FC = () => {
|
|||
}
|
||||
|
||||
setCurrentQuestion(quizQuestions[0]);
|
||||
webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex: 0, isLaunch: true});
|
||||
webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex: 0, isLaunch: true });
|
||||
};
|
||||
|
||||
const launchStudentMode = () => {
|
||||
|
|
@ -331,7 +333,7 @@ const ManageRoom: React.FC = () => {
|
|||
if (quiz?.content && quizQuestions) {
|
||||
setCurrentQuestion(quizQuestions[questionIndex]);
|
||||
if (quizMode === 'teacher') {
|
||||
webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex, isLaunch: false});
|
||||
webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex, isLaunch: false });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -425,10 +427,34 @@ const ManageRoom: React.FC = () => {
|
|||
<QuestionDisplay
|
||||
showAnswer={false}
|
||||
question={currentQuestion?.question as Question}
|
||||
|
||||
|
||||
/>
|
||||
)}
|
||||
|
||||
{quizMode === 'teacher' && (
|
||||
<div className="questionNavigationButtons">
|
||||
<div className="previousQuestionButton">
|
||||
<Button
|
||||
onClick={previousQuestion}
|
||||
variant="contained"
|
||||
disabled={Number(currentQuestion?.question.id) <= 1}
|
||||
>
|
||||
Question précédente
|
||||
</Button>
|
||||
</div>
|
||||
<div className="nextQuestionButton">
|
||||
<Button
|
||||
onClick={nextQuestion}
|
||||
variant="contained"
|
||||
disabled={
|
||||
Number(currentQuestion?.question.id) >=
|
||||
quizQuestions.length
|
||||
}
|
||||
>
|
||||
Prochaine question
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<LiveResultsComponent
|
||||
quizMode={quizMode}
|
||||
socket={socket}
|
||||
|
|
@ -439,34 +465,7 @@ const ManageRoom: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{quizMode === 'teacher' && (
|
||||
<div
|
||||
className="questionNavigationButtons"
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
>
|
||||
<div className="previousQuestionButton">
|
||||
<Button
|
||||
onClick={previousQuestion}
|
||||
variant="contained"
|
||||
disabled={Number(currentQuestion?.question.id) <= 1}
|
||||
>
|
||||
Question précédente
|
||||
</Button>
|
||||
</div>
|
||||
<div className="nextQuestionButton">
|
||||
<Button
|
||||
onClick={nextQuestion}
|
||||
variant="contained"
|
||||
disabled={
|
||||
Number(currentQuestion?.question.id) >=
|
||||
quizQuestions.length
|
||||
}
|
||||
>
|
||||
Prochaine question
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
) : (
|
||||
<StudentWaitPage
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@
|
|||
justify-content: center;
|
||||
/* align-items: center; */
|
||||
}
|
||||
.questionNavigationButtons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue