From 1981a7f7d54437709633330957b394541fa4b7e2 Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Tue, 25 Mar 2025 03:53:25 -0400 Subject: [PATCH 1/6] UI improvements --- .../GIFTCheatSheet/GiftCheatSheet.tsx | 32 +- client/src/components/Header/Header.tsx | 4 +- .../TrueFalseQuestionDisplay.tsx | 2 - .../StudentWaitPage/StudentWaitPage.tsx | 9 +- .../TeacherModeQuiz/TeacherModeQuiz.tsx | 2 +- .../providers/SimpleLogin/Login.tsx | 2 - .../src/pages/Teacher/Dashboard/Dashboard.tsx | 502 ++++++++++-------- .../pages/Teacher/EditorQuiz/EditorQuiz.tsx | 2 + .../pages/Teacher/ManageRoom/ManageRoom.tsx | 28 +- .../pages/Teacher/ManageRoom/manageRoom.css | 179 +------ client/src/pages/Teacher/Share/Share.tsx | 2 + 11 files changed, 364 insertions(+), 400 deletions(-) diff --git a/client/src/components/GIFTCheatSheet/GiftCheatSheet.tsx b/client/src/components/GIFTCheatSheet/GiftCheatSheet.tsx index 036f2d0..0d22eae 100644 --- a/client/src/components/GIFTCheatSheet/GiftCheatSheet.tsx +++ b/client/src/components/GIFTCheatSheet/GiftCheatSheet.tsx @@ -1,6 +1,7 @@ // GiftCheatSheet.tsx import React, { useState } from 'react'; import './giftCheatSheet.css'; +import FileCopyIcon from '@mui/icons-material/FileCopy'; const GiftCheatSheet: React.FC = () => { const [copySuccess, setCopySuccess] = useState(false); @@ -19,7 +20,7 @@ const GiftCheatSheet: React.FC = () => { console.error('Erreur lors de la copie dans le presse-papiers : ', error); }); }; - + const QuestionVraiFaux = "::Exemple de question vrai/faux:: \n 2+2 \\= 4 ? {T} //Utilisez les valeurs {T}, {F}, {TRUE} et {FALSE}."; const QuestionChoixMul = "::Ville capitale du Canada:: \nQuelle ville est la capitale du Canada? {\n~ Toronto\n~ Montréal\n= Ottawa #Rétroaction spécifique.\n} // Commentaire non visible (au besoin)"; @@ -42,7 +43,10 @@ const GiftCheatSheet: React.FC = () => { - +
@@ -54,7 +58,10 @@ const GiftCheatSheet: React.FC = () => { } - +

3. Questions à choix multiple avec plusieurs réponses

@@ -65,7 +72,10 @@ const GiftCheatSheet: React.FC = () => { } - +
@@ -75,7 +85,10 @@ const GiftCheatSheet: React.FC = () => { {QuestionCourte} - +
@@ -87,7 +100,10 @@ const GiftCheatSheet: React.FC = () => { } - +
@@ -185,7 +201,7 @@ const GiftCheatSheet: React.FC = () => { Attention: l'ancienne fonctionnalité avec les balises {''} n'est plus supportée.

-
+

10. Informations supplémentaires

@@ -199,6 +215,6 @@ const GiftCheatSheet: React.FC = () => {

); -}; +}; export default GiftCheatSheet; diff --git a/client/src/components/Header/Header.tsx b/client/src/components/Header/Header.tsx index 016d23e..71f0a79 100644 --- a/client/src/components/Header/Header.tsx +++ b/client/src/components/Header/Header.tsx @@ -2,6 +2,7 @@ import { Link, useNavigate } from 'react-router-dom'; import * as React from 'react'; import './header.css'; import { Button } from '@mui/material'; +import ExitToAppIcon from '@mui/icons-material/ExitToApp'; interface HeaderProps { isLoggedIn: boolean; @@ -28,8 +29,9 @@ const Header: React.FC = ({ isLoggedIn, handleLogout }) => { handleLogout(); navigate('/'); }} + startIcon={} > - Logout + Déconnexion )} diff --git a/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx index 717cdbe..7decbab 100644 --- a/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx @@ -59,7 +59,6 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { disabled={disableButton} > {showAnswer ? (
{(question.isTrue ? '✅' : '❌')}
) : ``} -
V
Vrai
{showAnswer && answer && question.trueFormattedFeedback && ( @@ -76,7 +75,6 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { > {showAnswer ? (
{(!question.isTrue ? '✅' : '❌')}
) : ``} -
F
Faux
{showAnswer && !answer && question.falseFormattedFeedback && ( diff --git a/client/src/components/StudentWaitPage/StudentWaitPage.tsx b/client/src/components/StudentWaitPage/StudentWaitPage.tsx index c5de4f2..52f8958 100644 --- a/client/src/components/StudentWaitPage/StudentWaitPage.tsx +++ b/client/src/components/StudentWaitPage/StudentWaitPage.tsx @@ -21,16 +21,15 @@ const StudentWaitPage: React.FC = ({ students, launchQuiz, setQuizMode }) return (
-
+
+ Lancer +
diff --git a/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx b/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx index 8925c09..ca67aba 100644 --- a/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx +++ b/client/src/components/TeacherModeQuiz/TeacherModeQuiz.tsx @@ -116,7 +116,7 @@ const TeacherModeQuiz: React.FC = ({ diff --git a/client/src/pages/AuthManager/providers/SimpleLogin/Login.tsx b/client/src/pages/AuthManager/providers/SimpleLogin/Login.tsx index ecc9a1c..e0d4988 100644 --- a/client/src/pages/AuthManager/providers/SimpleLogin/Login.tsx +++ b/client/src/pages/AuthManager/providers/SimpleLogin/Login.tsx @@ -44,7 +44,6 @@ const SimpleLogin: React.FC = () => { variant="outlined" value={email} onChange={(e) => setEmail(e.target.value)} - placeholder="Nom d'utilisateur" sx={{ marginBottom: '1rem' }} fullWidth /> @@ -55,7 +54,6 @@ const SimpleLogin: React.FC = () => { type="password" value={password} onChange={(e) => setPassword(e.target.value)} - placeholder="Nom de la salle" sx={{ marginBottom: '1rem' }} fullWidth /> diff --git a/client/src/pages/Teacher/Dashboard/Dashboard.tsx b/client/src/pages/Teacher/Dashboard/Dashboard.tsx index cdae619..9d84bbb 100644 --- a/client/src/pages/Teacher/Dashboard/Dashboard.tsx +++ b/client/src/pages/Teacher/Dashboard/Dashboard.tsx @@ -105,7 +105,7 @@ const Dashboard: React.FC = () => { fetchData(); }, []); - + useEffect(() => { if (rooms.length > 0 && !selectedRoom) { selectRoom(rooms[rooms.length - 1]); @@ -121,41 +121,41 @@ const Dashboard: React.FC = () => { } }; - // Créer une salle - const createRoom = async (title: string) => { - // Créer la salle et récupérer l'objet complet - const newRoom = await ApiService.createRoom(title); - - // Mettre à jour la liste des salles - const updatedRooms = await ApiService.getUserRooms(); - setRooms(updatedRooms as RoomType[]); - - // Sélectionner la nouvelle salle avec son ID - selectRoomByName(newRoom); // Utiliser l'ID de l'objet retourné - }; + // Créer une salle + const createRoom = async (title: string) => { + // Créer la salle et récupérer l'objet complet + const newRoom = await ApiService.createRoom(title); + + // Mettre à jour la liste des salles + const updatedRooms = await ApiService.getUserRooms(); + setRooms(updatedRooms as RoomType[]); + + // Sélectionner la nouvelle salle avec son ID + selectRoomByName(newRoom); // Utiliser l'ID de l'objet retourné + }; - // Sélectionner une salle - const selectRoomByName = (roomId: string) => { + // Sélectionner une salle + const selectRoomByName = (roomId: string) => { const room = rooms.find(r => r._id === roomId); - selectRoom(room); - localStorage.setItem('selectedRoomId', roomId); - }; + selectRoom(room); + localStorage.setItem('selectedRoomId', roomId); + }; - const handleCreateRoom = async () => { - if (newRoomTitle.trim()) { - try { + const handleCreateRoom = async () => { + if (newRoomTitle.trim()) { + try { await createRoom(newRoomTitle); const userRooms = await ApiService.getUserRooms(); setRooms(userRooms as RoomType[]); - setOpenAddRoomDialog(false); - setNewRoomTitle(''); - } catch (error) { + setOpenAddRoomDialog(false); + setNewRoomTitle(''); + } catch (error) { setErrorMessage(error instanceof Error ? error.message : "Erreur inconnue"); - setShowErrorDialog(true); - } - } - }; + setShowErrorDialog(true); + } + } + }; const handleSelectFolder = (event: React.ChangeEvent) => { setSelectedFolderId(event.target.value); @@ -398,7 +398,7 @@ const Dashboard: React.FC = () => { } else { const randomSixDigit = Math.floor(100000 + Math.random() * 900000); navigate(`/teacher/manage-room/${quiz._id}/${randomSixDigit}`); - } + } }; const handleShareQuiz = async (quiz: QuizType) => { @@ -425,30 +425,63 @@ const Dashboard: React.FC = () => { return (
-
Tableau de bord
+ {/* Conteneur pour le titre et le sélecteur de salle */} +
+ {/* Titre tableau de bord */} +
+ Tableau de bord +
-
- - handleSelectRoom(e)} + id="room-select" + style={{ + padding: '8px 12px', + fontSize: '14px', + borderRadius: '8px', + border: '1px solid #ccc', + backgroundColor: '#fff', + maxWidth: '200px', + cursor: 'pointer', + fontWeight: '500' + }} + > + - ))} - - - + {rooms.map((room) => ( + + ))} + + +
- {selectedRoom && ( -
-

Salle sélectionnée: {selectedRoom.title}

-
- )} - + {/* Dialog pour créer une salle */} setOpenAddRoomDialog(false)}> Créer une nouvelle salle @@ -463,6 +496,8 @@ const Dashboard: React.FC = () => { + + {/* Dialog d'erreur */} setShowErrorDialog(false)}> Erreur @@ -473,193 +508,238 @@ const Dashboard: React.FC = () => { -
- - - - - - ) - }} - /> +
+
+ + + + + + ) + }} + sx={{ + '& .MuiOutlinedInput-root': { + borderRadius: '8px', + '& fieldset': { + borderColor: '#e0e0e0' + }, + '&:hover fieldset': { + borderColor: '#5271FF' + } + } + }} + /> +
+ +
+ + + +
-
-
+ {/* Conteneur principal avec les actions et la liste des quiz */} +
+ {/* Barre d'outils pour le sélecteur de dossier et les actions */} +
+ {/* Sélecteur de dossier */} - - - {folders.map((folder: FolderType) => ( + + {folders.map((folder) => ( ))} + + {/* Actions dossiers */} +
+ + + + + + + + + + + + + + + + + + + + +
-
- - - {' '} - {' '} - - - - -
- + {Object.keys(quizzesByFolder).map((folderName) => ( + - {' '} - {' '} - -
-
- - -
- - {' '} - {' '} - -
-
- - -
- - {' '} - {' '} - -
-
-
-
- -
- - - -
-
- {Object.keys(quizzesByFolder).map((folderName) => ( - -
{folderName}
- - {quizzesByFolder[folderName].map((quiz: QuizType) => ( -
-
- -
+
+ {folderName} +
+ + {quizzesByFolder[folderName].map((quiz) => ( +
+
+ -
- + +
+ +
+ + downloadTxtFile(quiz)} + > + + + + + + handleEditQuiz(quiz)} + > + + + + + + handleDuplicateQuiz(quiz)} + > + + + + + + handleRemoveQuiz(quiz)} + > + + + + + + handleShareQuiz(quiz)} + > + + + +
- -
- - downloadTxtFile(quiz)} - > - {' '} - {' '} - - - - - handleEditQuiz(quiz)} - > - {' '} - {' '} - - - - - handleDuplicateQuiz(quiz)} - > - {' '} - {' '} - - - - - handleRemoveQuiz(quiz)} - > - {' '} - {' '} - - - - - handleShareQuiz(quiz)} - > - {' '} - {' '} - - -
-
- ))} - - - ))} + ))} + + + ))} +
+ + {/* Modal d'importation */} setShowImportModal(false)} diff --git a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx index 89f822a..12eafcd 100644 --- a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx +++ b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx @@ -17,6 +17,7 @@ import ReturnButton from 'src/components/ReturnButton/ReturnButton'; import ApiService from '../../../services/ApiService'; import { escapeForGIFT } from '../../../utils/giftUtils'; import { Upload } from '@mui/icons-material'; +import SaveIcon from '@mui/icons-material/Save'; interface EditQuizParams { id: string; @@ -244,6 +245,7 @@ const QuizForm: React.FC = () => { diff --git a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx index 8c3d699..67d403b 100644 --- a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx +++ b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx @@ -35,19 +35,19 @@ const ManageRoom: React.FC = () => { const [formattedRoomName, setFormattedRoomName] = useState(""); const [newlyConnectedUser, setNewlyConnectedUser] = useState(null); - // 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 useEffect(() => { 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) { @@ -138,8 +138,8 @@ const ManageRoom: React.FC = () => { setFormattedRoomName(roomNameUpper); console.log(`Creating WebSocket room named ${roomNameUpper}`); - /** - * ATTENTION: Lire les variables d'état dans + /** + * ATTENTION: Lire les variables d'état dans * les .on() n'est pas une bonne pratique. * Les valeurs sont celles au moment de la création * de la fonction et non au moment de l'exécution. @@ -254,8 +254,8 @@ const ManageRoom: React.FC = () => { setCurrentQuestion(quizQuestions[nextQuestionIndex]); webSocketService.nextQuestion({roomName: formattedRoomName, - questions: quizQuestions, - questionIndex: nextQuestionIndex, + questions: quizQuestions, + questionIndex: nextQuestionIndex, isLaunch: false}); }; @@ -382,15 +382,19 @@ const ManageRoom: React.FC = () => { width: '100%' }} > - {( + {
{students.length}/60
- )} + }
diff --git a/client/src/pages/Teacher/ManageRoom/manageRoom.css b/client/src/pages/Teacher/ManageRoom/manageRoom.css index ad870a9..ece7043 100644 --- a/client/src/pages/Teacher/ManageRoom/manageRoom.css +++ b/client/src/pages/Teacher/ManageRoom/manageRoom.css @@ -1,26 +1,33 @@ - .room .roomHeader { width: 100%; display: flex; - flex-direction: row; - justify-content: space-between; - align-content: stretch + flex-direction: column; + align-items: flex-start; + position: relative; } -.room .roomHeader .returnButton { - flex-basis: 10%; - display: flex; - justify-content: center; +.room .roomHeader .returnButton { + position: absolute; + top: 10px; + left: 0; + z-index: 10; } .room .roomHeader .centerTitle { flex-basis: auto; - display: flex; flex-direction: column; - justify-content: flex-end; - align-items: flex-end; + justify-content: flex-start; + align-items: flex-start; + margin-top: 40px; +} +.room .roomHeader .headerContent { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 60px; } .room .roomHeader .dumb { @@ -31,155 +38,11 @@ width: 100%; height: 70vh; display: flex; - overflow: auto; justify-content: center; - /* align-items: center; */ } - - - - - -/* .create-room-container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100%; +.room h1 { + text-align: center; + margin-top: 50px; } - -.manage-room-container { - display: flex; - flex-direction: column; - align-items: center; - height: 100%; - width: 100%; -} - -.quiz-setup-container { - display: flex; - flex-direction: column; - width: 100%; - margin-top: 2rem; -} - -.quiz-mode-selection { - display: flex; - flex-grow: 0; - flex-direction: column; - justify-content: center; - align-items: center; - margin-top: 10px; - height: 15vh; -} - -.users-container { - display: flex; - flex-direction: column; - align-items: center; - flex-grow: 1; - gap: 2vh; -} - -.launch-quiz-btn { - width: 20vw; - height: 11vh; - margin-top: 2vh; - box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); -} - -.mode-choice { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - width: 20vw; - margin-top: 2vh; -} - -.user { - background-color: #e7dad1; - padding: 10px 20px; - border: 1px solid black; - border-radius: 10px; - box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); -} - -.bottom-btn { - display: flex; - width: 100%; - justify-content: flex-end; - margin-top: 2vh; -} - -.room-container { - position: relative; - width: 100%; - max-width: 60vw; -} - -@media only screen and (max-device-width: 768px) { - .room-container { - max-width: 100%; - } -} - -.room-wrapper { - display: flex; - width: 100%; - height: 100%; - justify-content: center; -} - -.room-name-wrapper { - display: flex; - flex-direction: column; - align-items: end; -} -.user-item { - width: 100%; -} - -.flex-column-wrapper { - display: flex; - flex-direction: column; - height: 85vh; - overflow: auto; -} - -.preview-and-result-container { - display: flex; - flex-direction: column; - gap: 2rem; -} - -.nextQuestionButton { - align-self: flex-end; - margin-bottom: 5rem !important; -} - -.top-container { - display: flex; - justify-content: space-between; - align-items: center; -} - -@media only screen and (max-device-height: 4000px) { - .flex-column-wrapper { - height: 60vh; - } -} - -@media only screen and (max-device-height: 1079px) { - .flex-column-wrapper { - height: 50vh; - } -} - -@media only screen and (max-device-height: 741px) { - .flex-column-wrapper { - height: 40vh; - } -} */ diff --git a/client/src/pages/Teacher/Share/Share.tsx b/client/src/pages/Teacher/Share/Share.tsx index 0dc4fe7..1c2650d 100644 --- a/client/src/pages/Teacher/Share/Share.tsx +++ b/client/src/pages/Teacher/Share/Share.tsx @@ -10,6 +10,7 @@ import { Button, NativeSelect } from '@mui/material'; import ReturnButton from 'src/components/ReturnButton/ReturnButton'; import ApiService from '../../../services/ApiService'; +import SaveIcon from '@mui/icons-material/Save'; const Share: React.FC = () => { console.log('Component rendered'); @@ -119,6 +120,7 @@ const Share: React.FC = () => { From 5f4b97e004a6729d1cd8a10a93ac892faa423dac Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Tue, 25 Mar 2025 04:40:47 -0400 Subject: [PATCH 2/6] =?UTF-8?q?Am=C3=A9lioration=20bouton=20recherche=20qu?= =?UTF-8?q?iz?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/Teacher/Dashboard/Dashboard.tsx | 123 +++++++++++------- 1 file changed, 76 insertions(+), 47 deletions(-) diff --git a/client/src/pages/Teacher/Dashboard/Dashboard.tsx b/client/src/pages/Teacher/Dashboard/Dashboard.tsx index 9d84bbb..9b5ba1b 100644 --- a/client/src/pages/Teacher/Dashboard/Dashboard.tsx +++ b/client/src/pages/Teacher/Dashboard/Dashboard.tsx @@ -66,6 +66,7 @@ const Dashboard: React.FC = () => { const [selectedRoom, selectRoom] = useState(); // menu const [errorMessage, setErrorMessage] = useState(''); const [showErrorDialog, setShowErrorDialog] = useState(false); + const [isSearchVisible, setIsSearchVisible] = useState(false); // Filter quizzes based on search term // const filteredQuizzes = quizzes.filter(quiz => @@ -120,6 +121,9 @@ const Dashboard: React.FC = () => { selectRoomByName(event.target.value); } }; + const toggleSearchVisibility = () => { + setIsSearchVisible(!isSearchVisible); // Alterne entre afficher et cacher la barre de recherche + }; // Créer une salle const createRoom = async (title: string) => { @@ -511,62 +515,87 @@ const Dashboard: React.FC = () => {
-
- - - - - - ) - }} - sx={{ - '& .MuiOutlinedInput-root': { + {/* Barre de recherche avec un bouton d'icône qui s'affiche ou se cache */} +
+ {!isSearchVisible ? ( + + border: '1px solid #ccc', + padding: '8px 12px', + backgroundColor: '#fff', + color: '#5271FF' + }} + > + + + ) : ( + // Barre de recherche visible + + + + + + ) + }} + /> + )}
-
- + > + Ajouter nouveau quiz + - -
+ > + Importer +
{/* Conteneur principal avec les actions et la liste des quiz */} From 25024ebcc34930912fb5a73ec912ac94e0fe90a0 Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Tue, 25 Mar 2025 15:36:53 -0400 Subject: [PATCH 3/6] Modif --- .../StudentWaitPage/StudentWaitPage.tsx | 2 +- .../src/pages/Teacher/Dashboard/Dashboard.tsx | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/client/src/components/StudentWaitPage/StudentWaitPage.tsx b/client/src/components/StudentWaitPage/StudentWaitPage.tsx index 52f8958..db9b99e 100644 --- a/client/src/components/StudentWaitPage/StudentWaitPage.tsx +++ b/client/src/components/StudentWaitPage/StudentWaitPage.tsx @@ -21,7 +21,7 @@ const StudentWaitPage: React.FC = ({ students, launchQuiz, setQuizMode }) return (
-
+
))} From ac3930c55375efacb6306bd79de3b7b7df977c21 Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Tue, 25 Mar 2025 17:50:28 -0400 Subject: [PATCH 4/6] Bouton supprimer en rouge --- client/src/pages/Teacher/Dashboard/Dashboard.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/pages/Teacher/Dashboard/Dashboard.tsx b/client/src/pages/Teacher/Dashboard/Dashboard.tsx index 8003525..c1a1571 100644 --- a/client/src/pages/Teacher/Dashboard/Dashboard.tsx +++ b/client/src/pages/Teacher/Dashboard/Dashboard.tsx @@ -659,7 +659,7 @@ const Dashboard: React.FC = () => { @@ -751,7 +751,7 @@ const Dashboard: React.FC = () => { handleRemoveQuiz(quiz)} > From 0941a44e5035ee9e4215595edf6013d6a3b7407e Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Mon, 31 Mar 2025 22:19:24 -0400 Subject: [PATCH 5/6] =?UTF-8?q?Am=C3=A9liore=20page=20=20editor=20quiz?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/Teacher/EditorQuiz/EditorQuiz.tsx | 202 ++++++++++-------- .../pages/Teacher/ManageRoom/ManageRoom.tsx | 78 ++++--- 2 files changed, 170 insertions(+), 110 deletions(-) diff --git a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx index 12eafcd..74b9a21 100644 --- a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx +++ b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx @@ -11,7 +11,16 @@ import GIFTTemplatePreview from 'src/components/GiftTemplate/GIFTTemplatePreview import { QuizType } from '../../../Types/QuizType'; import './editorQuiz.css'; -import { Button, TextField, NativeSelect, Divider, Dialog, DialogTitle, DialogActions, DialogContent } from '@mui/material'; +import { + Button, + TextField, + NativeSelect, + Divider, + Dialog, + DialogTitle, + DialogActions, + DialogContent +} from '@mui/material'; import ReturnButton from 'src/components/ReturnButton/ReturnButton'; import ApiService from '../../../services/ApiService'; @@ -62,7 +71,7 @@ const QuizForm: React.FC = () => { }; }, []); - const scrollToImagesSection = (event: { preventDefault: () => void; }) => { + const scrollToImagesSection = (event: { preventDefault: () => void }) => { event.preventDefault(); const section = document.getElementById('images-section'); if (section) { @@ -87,10 +96,12 @@ const QuizForm: React.FC = () => { return; } - const quiz = await ApiService.getQuiz(id) as QuizType; + const quiz = (await ApiService.getQuiz(id)) as QuizType; if (!quiz) { - window.alert(`Une erreur est survenue.\n Le quiz ${id} n'a pas été trouvé\nVeuillez réessayer plus tard`) + window.alert( + `Une erreur est survenue.\n Le quiz ${id} n'a pas été trouvé\nVeuillez réessayer plus tard` + ); console.error('Quiz not found for id:', id); navigate('/teacher/dashboard'); return; @@ -103,9 +114,8 @@ const QuizForm: React.FC = () => { setSelectedFolder(folderId); setFilteredValue(content); setValue(quiz.content.join('\n\n')); - } catch (error) { - window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`) + window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`); console.error('Error fetching quiz:', error); navigate('/teacher/dashboard'); } @@ -120,7 +130,7 @@ const QuizForm: React.FC = () => { } // split value when there is at least one blank line - const linesArray = value.split(/\n{2,}/); + const linesArray = value.split(/\n{2,}/); // if the first item in linesArray is blank, remove it if (linesArray[0] === '') linesArray.shift(); @@ -138,12 +148,12 @@ const QuizForm: React.FC = () => { try { // check if everything is there if (quizTitle == '') { - alert("Veuillez choisir un titre"); + alert('Veuillez choisir un titre'); return; } if (selectedFolder == '') { - alert("Veuillez choisir un dossier"); + alert('Veuillez choisir un dossier'); return; } @@ -157,8 +167,8 @@ const QuizForm: React.FC = () => { navigate('/teacher/dashboard'); } catch (error) { - window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`) - console.log(error) + window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`); + console.log(error); } }; @@ -177,107 +187,122 @@ const QuizForm: React.FC = () => { } if (!inputElement.files || inputElement.files.length === 0) { - window.alert("Veuillez d'abord choisir une image à téléverser.") + window.alert("Veuillez d'abord choisir une image à téléverser."); return; } const imageUrl = await ApiService.uploadImage(inputElement.files[0]); // Check for errors - if(imageUrl.indexOf("ERROR") >= 0) { - window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`) + if (imageUrl.indexOf('ERROR') >= 0) { + window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`); return; } - setImageLinks(prevLinks => [...prevLinks, imageUrl]); + setImageLinks((prevLinks) => [...prevLinks, imageUrl]); // Reset the file input element if (fileInputRef.current) { fileInputRef.current.value = ''; } } catch (error) { - window.alert(`Une erreur est survenue.\n${error}\nVeuillez réessayer plus tard.`) - + window.alert(`Une erreur est survenue.\n${error}\nVeuillez réessayer plus tard.`); } }; const handleCopyToClipboard = async (link: string) => { navigator.clipboard.writeText(link); - } + }; return ( -
- -
+
+
-
Éditeur de quiz
- -
+
- {/*

Éditeur

*/} +
+
Éditeur de quiz
+
- - - - + + {folders.map((folder: FolderType) => ( + + ))} + +
-
- -
+
+
+ onEditorChange={handleUpdatePreview} + /> -
-
+
+
- setDialogOpen(false)} > + setDialogOpen(false)}> Erreur Veuillez d'abord choisir une image à téléverser. @@ -292,23 +317,32 @@ const QuizForm: React.FC = () => {

Mes images :

-
-
(Voir section
- -

9. Images

-
-
ci-dessous
-
)
+
+
(Voir section
+ + + +

9. Images

+
+
+
+
ci-dessous
+
)

- Cliquez sur un lien pour le copier -
-
    +
+
    {imageLinks.map((link, index) => { - const imgTag = `![alt_text](${escapeForGIFT(link)} "texte de l'infobulle")`; + const imgTag = `![alt_text](${escapeForGIFT( + link + )} "texte de l'infobulle")`; return (
  • - handleCopyToClipboard(imgTag)}> + handleCopyToClipboard(imgTag)}> {imgTag}
  • @@ -319,10 +353,9 @@ const QuizForm: React.FC = () => {
-
-
+

Prévisualisation

@@ -330,7 +363,6 @@ const QuizForm: React.FC = () => {
-
{showScrollButton && ( @@ -358,7 +390,7 @@ const scrollToTopButtonStyle: CSSProperties = { backgroundColor: '#5271ff', border: 'none', cursor: 'pointer', - zIndex: 1000, + zIndex: 1000 }; export default QuizForm; diff --git a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx index 67d403b..c840f44 100644 --- a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx +++ b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx @@ -25,14 +25,14 @@ const ManageRoom: React.FC = () => { const navigate = useNavigate(); const [socket, setSocket] = useState(null); const [students, setStudents] = useState([]); - const { quizId = '', roomName = '' } = useParams<{ quizId: string, roomName: string }>(); + const { quizId = '', roomName = '' } = useParams<{ quizId: string; roomName: string }>(); const [quizQuestions, setQuizQuestions] = useState(); const [quiz, setQuiz] = useState(null); const [quizMode, setQuizMode] = useState<'teacher' | 'student'>('teacher'); const [connectingError, setConnectingError] = useState(''); const [currentQuestion, setCurrentQuestion] = useState(undefined); const [quizStarted, setQuizStarted] = useState(false); - const [formattedRoomName, setFormattedRoomName] = useState(""); + const [formattedRoomName, setFormattedRoomName] = useState(''); const [newlyConnectedUser, setNewlyConnectedUser] = useState(null); // Handle the newly connected user in useEffect, because it needs state info @@ -179,7 +179,6 @@ const ManageRoom: React.FC = () => { }; useEffect(() => { - if (socket) { console.log(`Listening for submit-answer-room in room ${formattedRoomName}`); socket.on('submit-answer-room', (answerData: AnswerReceptionFromBackendType) => { @@ -253,10 +252,12 @@ const ManageRoom: React.FC = () => { if (nextQuestionIndex === undefined || nextQuestionIndex > quizQuestions.length - 1) return; setCurrentQuestion(quizQuestions[nextQuestionIndex]); - webSocketService.nextQuestion({roomName: formattedRoomName, + webSocketService.nextQuestion({ + roomName: formattedRoomName, questions: quizQuestions, questionIndex: nextQuestionIndex, - isLaunch: false}); + isLaunch: false + }); }; const previousQuestion = () => { @@ -266,7 +267,12 @@ 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 +300,12 @@ 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 +342,12 @@ 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 + }); } } }; @@ -365,7 +381,34 @@ const ManageRoom: React.FC = () => { return (
-

Salle : {formattedRoomName}

+
+

+ Salle : {formattedRoomName} +
+ {' '} + {students.length}/60 +
+

+
+
{ alignItems: 'center', width: '100%' }} - > - { -
- - {students.length}/60 -
- } -
+ >
@@ -429,7 +458,6 @@ const ManageRoom: React.FC = () => { )} From d242ccec34d242df8ab9ee843b7ab3f810deeed8 Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Tue, 1 Apr 2025 19:00:39 -0400 Subject: [PATCH 6/6] Replacement bouton quitter --- .../pages/Teacher/EditorQuiz/EditorQuiz.tsx | 3 +- .../pages/Teacher/ManageRoom/ManageRoom.tsx | 55 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx index 74b9a21..8cc1905 100644 --- a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx +++ b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx @@ -248,6 +248,7 @@ const QuizForm: React.FC = () => { { value={selectedFolder} onChange={handleSelectFolder} disabled={!isNewQuiz} - style={{ marginBottom: '16px', width: '200px', marginTop: '50px' }} + style={{ marginBottom: '16px', width: '200px', marginTop: '10px' }} >