mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Merge 9fbe2920cc into ee7a7a0544
This commit is contained in:
commit
498d7d2c1c
5 changed files with 220 additions and 60 deletions
|
|
@ -152,7 +152,7 @@ describe('LiveResults', () => {
|
||||||
expect(classAverageElement).toBeInTheDocument();
|
expect(classAverageElement).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('displays the correct answers per question', () => {
|
test('displays the correct answers per question in %', () => {
|
||||||
render(
|
render(
|
||||||
<LiveResults
|
<LiveResults
|
||||||
socket={mockSocket}
|
socket={mockSocket}
|
||||||
|
|
@ -175,4 +175,67 @@ describe('LiveResults', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('displays the submitted answer(s) in a question cell', () => {
|
||||||
|
render(
|
||||||
|
<LiveResults
|
||||||
|
socket={mockSocket}
|
||||||
|
questions={mockQuestions}
|
||||||
|
showSelectedQuestion={jest.fn()}
|
||||||
|
quizMode="teacher"
|
||||||
|
students={mockStudents}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show answers should be enabled
|
||||||
|
const showAnswersSwitch = screen.getByLabelText('Afficher les réponses');
|
||||||
|
// Toggle the display of answers is it's not already enabled
|
||||||
|
if (!(showAnswersSwitch as HTMLInputElement).checked) {
|
||||||
|
fireEvent.click(showAnswersSwitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
mockStudents.forEach((student) => {
|
||||||
|
student.answers.forEach((answer) => {
|
||||||
|
const chosenAnswerElements = screen.getAllByText(answer.answer.join(', '));
|
||||||
|
const chosenAnswerElement = chosenAnswerElements.find((element) => {
|
||||||
|
return element.closest('td')?.classList.contains('MuiTableCell-root');
|
||||||
|
});
|
||||||
|
expect(chosenAnswerElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('highlights the cell of the selected question', () => {
|
||||||
|
render(
|
||||||
|
<LiveResults
|
||||||
|
socket={mockSocket}
|
||||||
|
questions={mockQuestions}
|
||||||
|
showSelectedQuestion={jest.fn()}
|
||||||
|
quizMode="teacher"
|
||||||
|
students={mockStudents}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Select the first question
|
||||||
|
const questionCell = screen.getByText(`Q${1}`);
|
||||||
|
fireEvent.click(questionCell);
|
||||||
|
|
||||||
|
// Check if the selected question is highlighted
|
||||||
|
expect(questionCell.closest('th')?.classList.contains('selected-question')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Show answers should be enabled by default', () => {
|
||||||
|
render(
|
||||||
|
<LiveResults
|
||||||
|
socket={mockSocket}
|
||||||
|
questions={mockQuestions}
|
||||||
|
showSelectedQuestion={jest.fn()}
|
||||||
|
quizMode="teacher"
|
||||||
|
students={mockStudents}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const showAnswersSwitch = screen.getByLabelText('Afficher les réponses');
|
||||||
|
expect((showAnswersSwitch as HTMLInputElement).checked).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -75,36 +75,36 @@ describe('ManageRoom', () => {
|
||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
||||||
createSuccessCallback('Test Room');
|
createSuccessCallback('Test Room');
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id');
|
expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id');
|
||||||
});
|
});
|
||||||
|
|
||||||
const launchButton = screen.getByText('Lancer');
|
const launchButton = screen.getByText('Lancer');
|
||||||
fireEvent.click(launchButton);
|
fireEvent.click(launchButton);
|
||||||
|
|
||||||
const rythmeButton = screen.getByText('Rythme du professeur');
|
const rythmeButton = screen.getByText('Rythme du professeur');
|
||||||
fireEvent.click(rythmeButton);
|
fireEvent.click(rythmeButton);
|
||||||
|
|
||||||
const secondLaunchButton = screen.getAllByText('Lancer');
|
const secondLaunchButton = screen.getAllByText('Lancer');
|
||||||
fireEvent.click(secondLaunchButton[1]);
|
fireEvent.click(secondLaunchButton[1]);
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Test Quiz')).toBeInTheDocument();
|
expect(screen.getByText('Test Quiz')).toBeInTheDocument();
|
||||||
|
|
||||||
const roomHeader = document.querySelector('h1');
|
const roomHeader = document.querySelector('h1');
|
||||||
expect(roomHeader).toHaveTextContent('Salle : TEST ROOM');
|
expect(roomHeader).toHaveTextContent('Salle : TEST ROOM');
|
||||||
|
|
||||||
expect(screen.getByText('0/60')).toBeInTheDocument();
|
expect(screen.getByText('0/60')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Question 1/2')).toBeInTheDocument();
|
expect(screen.getByText('Question 1/2')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles create-success event', async () => {
|
test('handles create-success event', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(
|
render(
|
||||||
|
|
@ -171,30 +171,30 @@ describe('ManageRoom', () => {
|
||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
||||||
createSuccessCallback('Test Room');
|
createSuccessCallback('Test Room');
|
||||||
});
|
});
|
||||||
|
|
||||||
fireEvent.click(screen.getByText('Lancer'));
|
fireEvent.click(screen.getByText('Lancer'));
|
||||||
fireEvent.click(screen.getByText('Rythme du professeur'));
|
fireEvent.click(screen.getByText('Rythme du professeur'));
|
||||||
fireEvent.click(screen.getAllByText('Lancer')[1]);
|
fireEvent.click(screen.getAllByText('Lancer')[1]);
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
screen.debug();
|
screen.debug();
|
||||||
});
|
});
|
||||||
|
|
||||||
const nextQuestionButton = await screen.findByRole('button', { name: /Prochaine question/i });
|
const nextQuestionButton = await screen.findByRole('button', { name: /Prochaine question/i });
|
||||||
expect(nextQuestionButton).toBeInTheDocument();
|
expect(nextQuestionButton).toBeInTheDocument();
|
||||||
|
|
||||||
fireEvent.click(nextQuestionButton);
|
fireEvent.click(nextQuestionButton);
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Question 2/2')).toBeInTheDocument();
|
expect(screen.getByText('Question 2/2')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles disconnect', async () => {
|
test('handles disconnect', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(
|
render(
|
||||||
|
|
@ -230,38 +230,38 @@ describe('ManageRoom', () => {
|
||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
||||||
createSuccessCallback('Test Room');
|
createSuccessCallback('Test Room');
|
||||||
});
|
});
|
||||||
|
|
||||||
const launchButton = screen.getByText('Lancer');
|
const launchButton = screen.getByText('Lancer');
|
||||||
fireEvent.click(launchButton);
|
fireEvent.click(launchButton);
|
||||||
|
|
||||||
const rythmeButton = screen.getByText('Rythme du professeur');
|
const rythmeButton = screen.getByText('Rythme du professeur');
|
||||||
fireEvent.click(rythmeButton);
|
fireEvent.click(rythmeButton);
|
||||||
|
|
||||||
const secondLaunchButton = screen.getAllByText('Lancer');
|
const secondLaunchButton = screen.getAllByText('Lancer');
|
||||||
fireEvent.click(secondLaunchButton[1]);
|
fireEvent.click(secondLaunchButton[1]);
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const userJoinedCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'user-joined')[1];
|
const userJoinedCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'user-joined')[1];
|
||||||
userJoinedCallback(mockStudents[0]);
|
userJoinedCallback(mockStudents[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const submitAnswerCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'submit-answer-room')[1];
|
const submitAnswerCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'submit-answer-room')[1];
|
||||||
submitAnswerCallback(mockAnswerData);
|
submitAnswerCallback(mockAnswerData);
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
// console.info(consoleSpy.mock.calls);
|
// console.info(consoleSpy.mock.calls);
|
||||||
expect(consoleSpy).toHaveBeenCalledWith(
|
expect(consoleSpy).toHaveBeenCalledWith(
|
||||||
'Received answer from Student 1 for question 1: Answer1'
|
'Received answer from Student 1 for question 1: Answer1'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
consoleSpy.mockRestore();
|
consoleSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -294,5 +294,66 @@ describe('ManageRoom', () => {
|
||||||
expect(screen.queryByText('Student 1')).not.toBeInTheDocument();
|
expect(screen.queryByText('Student 1')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
test('initializes isQuestionShown based on quizMode', async() => {
|
||||||
|
render(<MemoryRouter>
|
||||||
|
<ManageRoom />
|
||||||
|
</MemoryRouter>);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
||||||
|
createSuccessCallback('Test Room');
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id');
|
||||||
|
});
|
||||||
|
const launchButton = screen.getByText('Lancer');
|
||||||
|
fireEvent.click(launchButton);
|
||||||
|
|
||||||
|
const rythmeButton = screen.getByText(`Rythme de l'étudiant`);
|
||||||
|
fireEvent.click(rythmeButton);
|
||||||
|
|
||||||
|
const secondLaunchButton = screen.getAllByText('Lancer');
|
||||||
|
fireEvent.click(secondLaunchButton[1]);
|
||||||
|
|
||||||
|
expect(screen.queryByText('Question')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('renders the close button when quizMode is student and isQuestionShown is true', async() => {
|
||||||
|
render(<MemoryRouter>
|
||||||
|
<ManageRoom />
|
||||||
|
</MemoryRouter>);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1];
|
||||||
|
createSuccessCallback('Test Room');
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id');
|
||||||
|
});
|
||||||
|
|
||||||
|
const launchButton = screen.getByText('Lancer');
|
||||||
|
fireEvent.click(launchButton);
|
||||||
|
|
||||||
|
const rythmeButton = screen.getByText(`Rythme de l'étudiant`);
|
||||||
|
fireEvent.click(rythmeButton);
|
||||||
|
|
||||||
|
const secondLaunchButton = screen.getAllByText('Lancer');
|
||||||
|
fireEvent.click(secondLaunchButton[1]);
|
||||||
|
|
||||||
|
const tableHeader = screen.getByText('Q1');
|
||||||
|
fireEvent.click(tableHeader);
|
||||||
|
|
||||||
|
const questionVisibilitySwitch = screen.getByTestId('question-visibility-switch'); // Get the specific switch
|
||||||
|
expect(screen.getByText(/Question 1\//i)).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.click(questionVisibilitySwitch);
|
||||||
|
|
||||||
|
expect(screen.queryByRole('button', { name: /✖/i })).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByText(/Question 1\//i)).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,11 @@ const LiveResultsTableFooter: React.FC<LiveResultsFooterProps> = ({
|
||||||
const answer = student.answers.find(
|
const answer = student.answers.find(
|
||||||
(answer) => parseInt(answer.idQuestion.toString()) === index + 1
|
(answer) => parseInt(answer.idQuestion.toString()) === index + 1
|
||||||
);
|
);
|
||||||
const answerText = answer ? answer.answer.toString() : '';
|
const answerText = answer
|
||||||
|
? Array.isArray(answer.answer)
|
||||||
|
? answer.answer.join(', ') // Join array elements with a space or another delimiter
|
||||||
|
: "" // never reached
|
||||||
|
: '';
|
||||||
const isCorrect = answer ? answer.isCorrect : false;
|
const isCorrect = answer ? answer.isCorrect : false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -63,6 +67,7 @@ const LiveResultsTableFooter: React.FC<LiveResultsFooterProps> = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{showCorrectAnswers ? (
|
{showCorrectAnswers ? (
|
||||||
|
// strips out formatting of answer text here (it will break images, katex, etc.)
|
||||||
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate({ format: '', text: answerText }) }}></div>
|
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate({ format: '', text: answerText }) }}></div>
|
||||||
) : isCorrect ? (
|
) : isCorrect ? (
|
||||||
<FontAwesomeIcon icon={faCheck} aria-label="correct" />
|
<FontAwesomeIcon icon={faCheck} aria-label="correct" />
|
||||||
|
|
@ -91,4 +96,4 @@ const LiveResultsTableFooter: React.FC<LiveResultsFooterProps> = ({
|
||||||
</TableBody>
|
</TableBody>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default LiveResultsTableFooter;
|
export default LiveResultsTableFooter;
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton';
|
||||||
import QuestionDisplay from 'src/components/QuestionsDisplay/QuestionDisplay';
|
import QuestionDisplay from 'src/components/QuestionsDisplay/QuestionDisplay';
|
||||||
import ApiService from '../../../services/ApiService';
|
import ApiService from '../../../services/ApiService';
|
||||||
import { QuestionType } from 'src/Types/QuestionType';
|
import { QuestionType } from 'src/Types/QuestionType';
|
||||||
import { Button } from '@mui/material';
|
import { Button, FormControlLabel, Switch } from '@mui/material';
|
||||||
import { checkIfIsCorrect } from './useRooms';
|
import { checkIfIsCorrect } from './useRooms';
|
||||||
|
|
||||||
const ManageRoom: React.FC = () => {
|
const ManageRoom: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [socket, setSocket] = useState<Socket | null>(null);
|
const [socket, setSocket] = useState<Socket | null>(null);
|
||||||
const [students, setStudents] = useState<StudentType[]>([]);
|
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 [quizQuestions, setQuizQuestions] = useState<QuestionType[] | undefined>();
|
||||||
const [quiz, setQuiz] = useState<QuizType | null>(null);
|
const [quiz, setQuiz] = useState<QuizType | null>(null);
|
||||||
const [quizMode, setQuizMode] = useState<'teacher' | 'student'>('teacher');
|
const [quizMode, setQuizMode] = useState<'teacher' | 'student'>('teacher');
|
||||||
|
|
@ -34,6 +34,7 @@ const ManageRoom: React.FC = () => {
|
||||||
const [quizStarted, setQuizStarted] = useState<boolean>(false);
|
const [quizStarted, setQuizStarted] = useState<boolean>(false);
|
||||||
const [formattedRoomName, setFormattedRoomName] = useState("");
|
const [formattedRoomName, setFormattedRoomName] = useState("");
|
||||||
const [newlyConnectedUser, setNewlyConnectedUser] = useState<StudentType | null>(null);
|
const [newlyConnectedUser, setNewlyConnectedUser] = useState<StudentType | null>(null);
|
||||||
|
const [isQuestionShown, setIsQuestionShown] = useState<boolean>(quizMode === 'student' ? false : true);
|
||||||
|
|
||||||
// Handle the newly connected user in useEffect, because it needs state info
|
// Handle the newly connected user in useEffect, because it needs state info
|
||||||
// not available in the socket.on() callback
|
// not available in the socket.on() callback
|
||||||
|
|
@ -41,13 +42,13 @@ const ManageRoom: React.FC = () => {
|
||||||
if (newlyConnectedUser) {
|
if (newlyConnectedUser) {
|
||||||
console.log(`Handling newly connected user: ${newlyConnectedUser.name}`);
|
console.log(`Handling newly connected user: ${newlyConnectedUser.name}`);
|
||||||
setStudents((prevStudents) => [...prevStudents, newlyConnectedUser]);
|
setStudents((prevStudents) => [...prevStudents, newlyConnectedUser]);
|
||||||
|
|
||||||
// only send nextQuestion if the quiz has started
|
// only send nextQuestion if the quiz has started
|
||||||
if (!quizStarted) {
|
if (!quizStarted) {
|
||||||
console.log(`!quizStarted: returning.... `);
|
console.log(`!quizStarted: returning.... `);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quizMode === 'teacher') {
|
if (quizMode === 'teacher') {
|
||||||
webSocketService.nextQuestion({
|
webSocketService.nextQuestion({
|
||||||
roomName: formattedRoomName,
|
roomName: formattedRoomName,
|
||||||
|
|
@ -60,12 +61,16 @@ const ManageRoom: React.FC = () => {
|
||||||
} else {
|
} else {
|
||||||
console.error('Invalid quiz mode:', quizMode);
|
console.error('Invalid quiz mode:', quizMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the newly connected user state
|
// Reset the newly connected user state
|
||||||
setNewlyConnectedUser(null);
|
setNewlyConnectedUser(null);
|
||||||
}
|
}
|
||||||
}, [newlyConnectedUser]);
|
}, [newlyConnectedUser]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsQuestionShown(quizMode === 'student' ? false : true);
|
||||||
|
}, [quizMode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const verifyLogin = async () => {
|
const verifyLogin = async () => {
|
||||||
if (!ApiService.isLoggedIn()) {
|
if (!ApiService.isLoggedIn()) {
|
||||||
|
|
@ -91,7 +96,7 @@ const ManageRoom: React.FC = () => {
|
||||||
return () => {
|
return () => {
|
||||||
disconnectWebSocket();
|
disconnectWebSocket();
|
||||||
};
|
};
|
||||||
}, [roomName, navigate]);
|
}, [roomName, navigate]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (quizId) {
|
if (quizId) {
|
||||||
|
|
@ -213,14 +218,14 @@ const ManageRoom: React.FC = () => {
|
||||||
console.log(`Comparing ${ans.idQuestion} to ${idQuestion}`);
|
console.log(`Comparing ${ans.idQuestion} to ${idQuestion}`);
|
||||||
return ans.idQuestion === idQuestion
|
return ans.idQuestion === idQuestion
|
||||||
? {
|
? {
|
||||||
...ans,
|
...ans,
|
||||||
answer,
|
answer,
|
||||||
isCorrect: checkIfIsCorrect(
|
isCorrect: checkIfIsCorrect(
|
||||||
answer,
|
answer,
|
||||||
idQuestion,
|
idQuestion,
|
||||||
quizQuestions!
|
quizQuestions!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
: ans;
|
: ans;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -253,10 +258,12 @@ const ManageRoom: React.FC = () => {
|
||||||
if (nextQuestionIndex === undefined || nextQuestionIndex > quizQuestions.length - 1) return;
|
if (nextQuestionIndex === undefined || nextQuestionIndex > quizQuestions.length - 1) return;
|
||||||
|
|
||||||
setCurrentQuestion(quizQuestions[nextQuestionIndex]);
|
setCurrentQuestion(quizQuestions[nextQuestionIndex]);
|
||||||
webSocketService.nextQuestion({roomName: formattedRoomName,
|
webSocketService.nextQuestion({
|
||||||
questions: quizQuestions,
|
roomName: formattedRoomName,
|
||||||
questionIndex: nextQuestionIndex,
|
questions: quizQuestions,
|
||||||
isLaunch: false});
|
questionIndex: nextQuestionIndex,
|
||||||
|
isLaunch: false
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const previousQuestion = () => {
|
const previousQuestion = () => {
|
||||||
|
|
@ -266,7 +273,7 @@ const ManageRoom: React.FC = () => {
|
||||||
|
|
||||||
if (prevQuestionIndex === undefined || prevQuestionIndex < 0) return;
|
if (prevQuestionIndex === undefined || prevQuestionIndex < 0) return;
|
||||||
setCurrentQuestion(quizQuestions[prevQuestionIndex]);
|
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 = () => {
|
const initializeQuizQuestion = () => {
|
||||||
|
|
@ -294,7 +301,7 @@ const ManageRoom: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentQuestion(quizQuestions[0]);
|
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 = () => {
|
const launchStudentMode = () => {
|
||||||
|
|
@ -306,6 +313,7 @@ const ManageRoom: React.FC = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setQuizQuestions(quizQuestions);
|
setQuizQuestions(quizQuestions);
|
||||||
|
setCurrentQuestion(quizQuestions[0]);
|
||||||
webSocketService.launchStudentModeQuiz(formattedRoomName, quizQuestions);
|
webSocketService.launchStudentModeQuiz(formattedRoomName, quizQuestions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -331,9 +339,11 @@ const ManageRoom: React.FC = () => {
|
||||||
if (quiz?.content && quizQuestions) {
|
if (quiz?.content && quizQuestions) {
|
||||||
setCurrentQuestion(quizQuestions[questionIndex]);
|
setCurrentQuestion(quizQuestions[questionIndex]);
|
||||||
if (quizMode === 'teacher') {
|
if (quizMode === 'teacher') {
|
||||||
webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex, isLaunch: false});
|
webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex, isLaunch: false });
|
||||||
}
|
}
|
||||||
|
setIsQuestionShown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReturn = () => {
|
const handleReturn = () => {
|
||||||
|
|
@ -398,15 +408,35 @@ const ManageRoom: React.FC = () => {
|
||||||
|
|
||||||
{/* the following breaks the css (if 'room' classes are nested) */}
|
{/* the following breaks the css (if 'room' classes are nested) */}
|
||||||
<div className="">
|
<div className="">
|
||||||
|
|
||||||
{quizQuestions ? (
|
{quizQuestions ? (
|
||||||
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
<div className="title center-h-align mb-2">{quiz?.title}</div>
|
<div className="title center-h-align mb-2">{quiz?.title}</div>
|
||||||
{!isNaN(Number(currentQuestion?.question.id)) && (
|
|
||||||
<strong className="number of questions">
|
<div className='close-button-wrapper'>
|
||||||
Question {Number(currentQuestion?.question.id)}/
|
<FormControlLabel
|
||||||
{quizQuestions?.length}
|
label={<div className="text-sm">Afficher les questions</div>}
|
||||||
</strong>
|
control={
|
||||||
)}
|
<Switch
|
||||||
|
data-testid="question-visibility-switch" // Add a unique test ID
|
||||||
|
checked={isQuestionShown}
|
||||||
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
|
setIsQuestionShown(e.target.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!isNaN(Number(currentQuestion?.question.id))
|
||||||
|
&& isQuestionShown && (
|
||||||
|
<strong className="number of questions">
|
||||||
|
Question {Number(currentQuestion?.question.id)}/
|
||||||
|
{quizQuestions?.length}
|
||||||
|
</strong>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{quizMode === 'teacher' && (
|
{quizMode === 'teacher' && (
|
||||||
<div className="mb-1">
|
<div className="mb-1">
|
||||||
|
|
@ -421,11 +451,11 @@ const ManageRoom: React.FC = () => {
|
||||||
|
|
||||||
<div className="mb-2 flex-column-wrapper">
|
<div className="mb-2 flex-column-wrapper">
|
||||||
<div className="preview-and-result-container">
|
<div className="preview-and-result-container">
|
||||||
{currentQuestion && (
|
{currentQuestion && isQuestionShown && (
|
||||||
<QuestionDisplay
|
<QuestionDisplay
|
||||||
showAnswer={false}
|
showAnswer={false}
|
||||||
question={currentQuestion?.question as Question}
|
question={currentQuestion?.question as Question}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,11 @@
|
||||||
/* align-items: center; */
|
/* align-items: center; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.close-button-wrapper{
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* .create-room-container {
|
/* .create-room-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue