// Dashboard.tsx import { useNavigate } from 'react-router-dom'; import React, { useState, useEffect, useMemo } from 'react'; import { parse } from 'gift-pegjs'; import Template from 'src/components/GiftTemplate/templates'; import { QuizType } from '../../../Types/QuizType'; import { FolderType } from '../../../Types/FolderType'; // import { QuestionService } from '../../../services/QuestionService'; import ApiService from '../../../services/ApiService'; import './dashboard.css'; import ImportModal from 'src/components/ImportModal/ImportModal'; //import axios from 'axios'; import { TextField, IconButton, InputAdornment, Button, Card, Tooltip, NativeSelect, CardContent, styled, } from '@mui/material'; import { Search, DeleteOutline, FileDownload, Add, Upload, FolderCopy, ContentCopy, Edit, Share, // DriveFileMove } from '@mui/icons-material'; // Create a custom-styled Card component const CustomCard = styled(Card)({ overflow: 'visible', // Override the overflow property position: 'relative', margin: '40px 0 20px 0', // Add top margin to make space for the tab borderRadius: '8px', paddingTop: '20px', // Ensure content inside the card doesn't overlap with the tab }); const Dashboard: React.FC = () => { const navigate = useNavigate(); const [quizzes, setQuizzes] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [showImportModal, setShowImportModal] = useState(false); const [folders, setFolders] = useState([]); const [selectedFolderId, setSelectedFolderId] = useState(''); // Selected folder // Filter quizzes based on search term // const filteredQuizzes = quizzes.filter(quiz => // quiz.title.toLowerCase().includes(searchTerm.toLowerCase()) // ); const filteredQuizzes = useMemo(() => { return quizzes.filter( (quiz) => quiz && quiz.title && quiz.title.toLowerCase().includes(searchTerm.toLowerCase()) ); }, [quizzes, searchTerm]); // Group quizzes by folder const quizzesByFolder = filteredQuizzes.reduce((acc, quiz) => { if (!acc[quiz.folderName]) { acc[quiz.folderName] = []; } acc[quiz.folderName].push(quiz); return acc; }, {} as Record); useEffect(() => { const fetchData = async () => { if (!ApiService.isLoggedIn()) { navigate("/teacher/login"); return; } else { const userFolders = await ApiService.getUserFolders(); setFolders(userFolders as FolderType[]); } }; fetchData(); }, []); const handleSelectFolder = (event: React.ChangeEvent) => { setSelectedFolderId(event.target.value); }; useEffect(() => { const fetchQuizzesForFolder = async () => { if (selectedFolderId == '') { const folders = await ApiService.getUserFolders(); // HACK force user folders to load on first load console.log("show all quizes") let quizzes: QuizType[] = []; for (const folder of folders as FolderType[]) { const folderQuizzes = await ApiService.getFolderContent(folder._id); console.log("folder: ", folder.title, " quiz: ", folderQuizzes); // add the folder.title to the QuizType if the folderQuizzes is an array addFolderTitleToQuizzes(folderQuizzes, folder.title); quizzes = quizzes.concat(folderQuizzes as QuizType[]) } setQuizzes(quizzes as QuizType[]); } else { console.log("show some quizzes") const folderQuizzes = await ApiService.getFolderContent(selectedFolderId); console.log("folderQuizzes: ", folderQuizzes); // get the folder title from its id const folderTitle = folders.find((folder) => folder._id === selectedFolderId)?.title || ''; addFolderTitleToQuizzes(folderQuizzes, folderTitle); setQuizzes(folderQuizzes as QuizType[]); } }; fetchQuizzesForFolder(); }, [selectedFolderId]); const handleSearch = (event: React.ChangeEvent) => { setSearchTerm(event.target.value); }; const handleRemoveQuiz = async (quiz: QuizType) => { try { const confirmed = window.confirm('Voulez-vous vraiment supprimer ce quiz?'); if (confirmed) { await ApiService.deleteQuiz(quiz._id); const updatedQuizzes = quizzes.filter((q) => q._id !== quiz._id); setQuizzes(updatedQuizzes); } } catch (error) { console.error('Error removing quiz:', error); } }; const handleDuplicateQuiz = async (quiz: QuizType) => { try { await ApiService.duplicateQuiz(quiz._id); if (selectedFolderId == '') { const folders = await ApiService.getUserFolders(); // HACK force user folders to load on first load console.log("show all quizzes") let quizzes: QuizType[] = []; for (const folder of folders as FolderType[]) { const folderQuizzes = await ApiService.getFolderContent(folder._id); console.log("folder: ", folder.title, " quiz: ", folderQuizzes); addFolderTitleToQuizzes(folderQuizzes, folder.title); quizzes = quizzes.concat(folderQuizzes as QuizType[]); } setQuizzes(quizzes as QuizType[]); } else { console.log("show some quizzes") const folderQuizzes = await ApiService.getFolderContent(selectedFolderId); addFolderTitleToQuizzes(folderQuizzes, selectedFolderId); setQuizzes(folderQuizzes as QuizType[]); } } catch (error) { console.error('Error duplicating quiz:', error); } }; const handleOnImport = () => { setShowImportModal(true); }; const validateQuiz = (questions: string[]) => { if (!questions || questions.length === 0) { return false; } // Check if I can generate the Template for each question // Otherwise the quiz is invalid for (let i = 0; i < questions.length; i++) { try { // questions[i] = QuestionService.ignoreImgTags(questions[i]); const parsedItem = parse(questions[i]); Template(parsedItem[0]); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (error) { return false; } } return true; }; const downloadTxtFile = async (quiz: QuizType) => { try { const selectedQuiz = await ApiService.getQuiz(quiz._id) as QuizType; //quizzes.find((quiz) => quiz._id === quiz._id); if (!selectedQuiz) { throw new Error('Selected quiz not found'); } //const { title, content } = selectedQuiz; let quizContent = ""; const title = selectedQuiz.title; console.log(selectedQuiz.content); selectedQuiz.content.forEach((question, qIndex) => { const formattedQuestion = question.trim(); // console.log(formattedQuestion); if (formattedQuestion !== '') { quizContent += formattedQuestion + '\n'; if (qIndex !== selectedQuiz.content.length - 1) { quizContent += '\n'; } } }); if (!validateQuiz(selectedQuiz.content)) { window.alert('Attention! Ce quiz contient des questions invalides selon le format GIFT.'); } const blob = new Blob([quizContent], { type: 'text/plain' }); const a = document.createElement('a'); const filename = title; a.download = `${filename}.gift`; a.href = window.URL.createObjectURL(blob); a.click(); } catch (error) { console.error('Error exporting selected quiz:', error); } }; const handleCreateFolder = async () => { try { const folderTitle = prompt('Titre du dossier'); if (folderTitle) { await ApiService.createFolder(folderTitle); const userFolders = await ApiService.getUserFolders(); setFolders(userFolders as FolderType[]); const newlyCreatedFolder = userFolders[userFolders.length - 1] as FolderType; setSelectedFolderId(newlyCreatedFolder._id); } } catch (error) { console.error('Error creating folder:', error); } }; const handleDeleteFolder = async () => { try { const confirmed = window.confirm('Voulez-vous vraiment supprimer ce dossier?'); if (confirmed) { await ApiService.deleteFolder(selectedFolderId); const userFolders = await ApiService.getUserFolders(); setFolders(userFolders as FolderType[]); } const folders = await ApiService.getUserFolders(); // HACK force user folders to load on first load console.log("show all quizzes") let quizzes: QuizType[] = []; for (const folder of folders as FolderType[]) { const folderQuizzes = await ApiService.getFolderContent(folder._id); console.log("folder: ", folder.title, " quiz: ", folderQuizzes); quizzes = quizzes.concat(folderQuizzes as QuizType[]) } setQuizzes(quizzes as QuizType[]); setSelectedFolderId(''); } catch (error) { console.error('Error deleting folder:', error); } }; const handleRenameFolder = async () => { try { // folderId: string GET THIS FROM CURRENT FOLDER // currentTitle: string GET THIS FROM CURRENT FOLDER const newTitle = prompt('Entrée le nouveau nom du fichier', "Nouveau nom de dossier"); if (newTitle) { await ApiService.renameFolder(selectedFolderId, newTitle); const userFolders = await ApiService.getUserFolders(); setFolders(userFolders as FolderType[]); // refresh the page setSelectedFolderId(''); } } catch (error) { console.error('Error renaming folder:', error); } }; const handleDuplicateFolder = async () => { try { // folderId: string GET THIS FROM CURRENT FOLDER await ApiService.duplicateFolder(selectedFolderId); // TODO set the selected folder to be the duplicated folder const userFolders = await ApiService.getUserFolders(); setFolders(userFolders as FolderType[]); const newlyCreatedFolder = userFolders[userFolders.length - 1] as FolderType; setSelectedFolderId(newlyCreatedFolder._id); } catch (error) { console.error('Error duplicating folder:', error); } }; const handleCreateQuiz = () => { navigate("/teacher/editor-quiz/new"); } const handleEditQuiz = (quiz: QuizType) => { navigate(`/teacher/editor-quiz/${quiz._id}`); } const handleLancerQuiz = (quiz: QuizType) => { navigate(`/teacher/manage-room/${quiz._id}`); } const handleShareQuiz = async (quiz: QuizType) => { try { const email = prompt(`Veuillez saisir l'email de la personne avec qui vous souhaitez partager ce quiz`, ""); if (email) { const result = await ApiService.ShareQuiz(quiz._id, email); if (!result) { window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`) return; } window.alert(`Quiz partagé avec succès!`) } } catch (error) { console.error('Erreur lors du partage du quiz:', error); } } return (
Tableau de bord
) }} />
{folders.map((folder: FolderType) => ( ))}
{Object.keys(quizzesByFolder).map(folderName => (
{folderName}
{quizzesByFolder[folderName].map((quiz: QuizType) => (
downloadTxtFile(quiz)} > handleEditQuiz(quiz)} > handleDuplicateQuiz(quiz)} > handleRemoveQuiz(quiz)} > handleShareQuiz(quiz)} >
))}
))}
setShowImportModal(false)} handleOnImport={handleOnImport} selectedFolder={selectedFolderId} />
); }; export default Dashboard; function addFolderTitleToQuizzes(folderQuizzes: string | QuizType[], folderName: string) { if (Array.isArray(folderQuizzes)) folderQuizzes.forEach((quiz) => { quiz.folderName = folderName; console.log(`quiz: ${quiz.title} folder: ${quiz.folderName}`); }); }