mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
QuizToPDF modal and basic function done
This commit is contained in:
parent
cb069bebeb
commit
19130d8f44
5 changed files with 386 additions and 182 deletions
|
|
@ -1,2 +1,3 @@
|
|||
VITE_BACKEND_URL=http://localhost:4400
|
||||
VITE_BACKEND_SOCKET_URL=http://localhost:4400
|
||||
VITE_AZURE_BACKEND_URL=http://localhost:4400
|
||||
|
|
|
|||
383
client/package-lock.json
generated
383
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -27,6 +27,7 @@
|
|||
"esbuild": "^0.23.1",
|
||||
"gift-pegjs": "^2.0.0-beta.1",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jspdf": "^2.5.2",
|
||||
"katex": "^0.16.11",
|
||||
"marked": "^14.1.2",
|
||||
"nanoid": "^5.0.2",
|
||||
|
|
|
|||
121
client/src/components/DownloadQuizModal/DownloadQuizModal.tsx
Normal file
121
client/src/components/DownloadQuizModal/DownloadQuizModal.tsx
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Dialog, DialogTitle, DialogActions, Button, Tooltip, IconButton } from '@mui/material';
|
||||
import { FileDownload } from '@mui/icons-material';
|
||||
|
||||
import { QuizType } from '../../Types/QuizType';
|
||||
import ApiService from '../../services/ApiService';
|
||||
|
||||
import jsPDF from 'jspdf';
|
||||
|
||||
interface DownloadQuizModalProps {
|
||||
quiz: QuizType;
|
||||
}
|
||||
|
||||
const DownloadQuizModal: React.FC<DownloadQuizModalProps> = ({ quiz }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleOpenModal = () => setOpen(true);
|
||||
|
||||
const handleCloseModal = () => setOpen(false);
|
||||
|
||||
const handleDownload = async (format: 'txt' | 'pdf-with-answers' | 'pdf-without-answers') => {
|
||||
switch (format) {
|
||||
case 'txt':
|
||||
await downloadTxtFile(quiz);
|
||||
break;
|
||||
case 'pdf-with-answers':
|
||||
await downloadPdfFile(quiz, true);
|
||||
break;
|
||||
case 'pdf-without-answers':
|
||||
await downloadPdfFile(quiz, false);
|
||||
break;
|
||||
}
|
||||
handleCloseModal();
|
||||
};
|
||||
|
||||
const downloadTxtFile = async (quiz: QuizType) => {
|
||||
try {
|
||||
const selectedQuiz = await ApiService.getQuiz(quiz._id) as QuizType;
|
||||
if (!selectedQuiz) throw new Error('Quiz not found');
|
||||
|
||||
let quizContent = "";
|
||||
selectedQuiz.content.forEach((question) => {
|
||||
const formattedQuestion = question.trim();
|
||||
if (formattedQuestion !== '') quizContent += formattedQuestion + '\n\n';
|
||||
});
|
||||
|
||||
const blob = new Blob([quizContent], { type: 'text/plain' });
|
||||
const a = document.createElement('a');
|
||||
a.download = `${selectedQuiz.title}.gift`;
|
||||
a.href = window.URL.createObjectURL(blob);
|
||||
a.click();
|
||||
} catch (error) {
|
||||
console.error('Error exporting quiz:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const downloadPdfFile = async (quiz: QuizType, withAnswers: boolean) => {
|
||||
try {
|
||||
const selectedQuiz = await ApiService.getQuiz(quiz._id) as QuizType;
|
||||
if (!selectedQuiz) throw new Error('Quiz not found');
|
||||
|
||||
const doc = new jsPDF();
|
||||
doc.setFont("helvetica", "bold");
|
||||
doc.setFontSize(25);
|
||||
doc.text(selectedQuiz.title, 10, 15);
|
||||
|
||||
let yPosition = 40;
|
||||
doc.setFont("helvetica", "normal");
|
||||
doc.setFontSize(16);
|
||||
|
||||
selectedQuiz.content.forEach((question, index) => {
|
||||
let formattedQuestion = question.trim();
|
||||
|
||||
|
||||
if (!withAnswers) {
|
||||
formattedQuestion = formattedQuestion.replace(/::.*?::/g, '')
|
||||
.replace(/\/\/.*$/gm, '')
|
||||
.replace(/#[^\n]*/g, '')
|
||||
.replace(/=/g, '')
|
||||
.replace(/~/g, '')
|
||||
.replace(/\{(.*?)\}/g, '{$1}');
|
||||
}
|
||||
|
||||
const wrappedText = doc.splitTextToSize(`${index + 1}. ${formattedQuestion}`, 180);
|
||||
|
||||
doc.text(wrappedText, 10, yPosition);
|
||||
|
||||
yPosition += wrappedText.length * 10;
|
||||
});
|
||||
|
||||
const filename = withAnswers
|
||||
? `${selectedQuiz.title}_avec_reponses.pdf`
|
||||
: `${selectedQuiz.title}_sans_reponses.pdf`;
|
||||
|
||||
doc.save(filename);
|
||||
} catch (error) {
|
||||
console.error('Error exporting quiz as PDF:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="Télécharger quiz" placement="top">
|
||||
<IconButton color="primary" onClick={handleOpenModal}>
|
||||
<FileDownload />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<Dialog open={open} onClose={handleCloseModal} fullWidth maxWidth="xs">
|
||||
<DialogTitle sx={{ textAlign: "center" }}>Choisissez un format de téléchargement</DialogTitle>
|
||||
<DialogActions sx={{ display: "flex", justifyContent: "center", gap: 2 }}>
|
||||
<Button onClick={() => handleDownload('txt')}>GIFT</Button>
|
||||
<Button onClick={() => handleDownload('pdf-with-answers')}> PDF avec réponses</Button>
|
||||
<Button onClick={() => handleDownload('pdf-without-answers')}>PDF sans réponses</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DownloadQuizModal;
|
||||
|
|
@ -27,7 +27,6 @@ import {
|
|||
import {
|
||||
Search,
|
||||
DeleteOutline,
|
||||
FileDownload,
|
||||
Add,
|
||||
Upload,
|
||||
FolderCopy,
|
||||
|
|
@ -36,6 +35,7 @@ import {
|
|||
Share,
|
||||
// DriveFileMove
|
||||
} from '@mui/icons-material';
|
||||
import DownloadQuizModal from 'src/components/DownloadQuizModal/DownloadQuizModal';
|
||||
|
||||
// Create a custom-styled Card component
|
||||
const CustomCard = styled(Card)({
|
||||
|
|
@ -196,7 +196,7 @@ const Dashboard: React.FC = () => {
|
|||
// questions[i] = QuestionService.ignoreImgTags(questions[i]);
|
||||
const parsedItem = parse(questions[i]);
|
||||
Template(parsedItem[0]);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -205,47 +205,6 @@ const Dashboard: React.FC = () => {
|
|||
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');
|
||||
|
|
@ -299,7 +258,7 @@ const Dashboard: React.FC = () => {
|
|||
const renamedFolderId = selectedFolderId;
|
||||
const result = await ApiService.renameFolder(selectedFolderId, newTitle);
|
||||
|
||||
if (result !== true ) {
|
||||
if (result !== true) {
|
||||
window.alert(`Une erreur est survenue: ${result}`);
|
||||
return;
|
||||
}
|
||||
|
|
@ -481,12 +440,9 @@ const Dashboard: React.FC = () => {
|
|||
</div>
|
||||
|
||||
<div className='actions'>
|
||||
<Tooltip title="Télécharger quiz" placement="top">
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => downloadTxtFile(quiz)}
|
||||
> <FileDownload /> </IconButton>
|
||||
</Tooltip>
|
||||
<div className="dashboard">
|
||||
<DownloadQuizModal quiz={quiz} />
|
||||
</div>
|
||||
|
||||
<Tooltip title="Modifier quiz" placement="top">
|
||||
<IconButton
|
||||
|
|
|
|||
Loading…
Reference in a new issue