editor question per question, delete and add question works

This commit is contained in:
Philippe 2025-03-12 13:43:11 -04:00
parent ee7a7a0544
commit cf2083ff85
2 changed files with 81 additions and 46 deletions

View file

@ -1,36 +1,70 @@
// Editor.tsx import React from 'react';
import React, { useState, useRef } from 'react'; import { TextField, Typography, IconButton, Box } from '@mui/material';
import './editor.css'; import DeleteIcon from '@mui/icons-material/Delete'; // Import delete icon
import { TextareaAutosize } from '@mui/material';
interface EditorProps { interface EditorProps {
label: string; label: string;
initialValue: string; values: string[];
onEditorChange: (value: string) => void; onValuesChange: (values: string[]) => void;
} }
const Editor: React.FC<EditorProps> = ({ initialValue, onEditorChange, label }) => { const Editor: React.FC<EditorProps> = ({ label, values, onValuesChange }) => {
const [value, setValue] = useState(initialValue); const handleChange = (index: number) => (event: React.ChangeEvent<HTMLInputElement>) => {
const editorRef = useRef<HTMLTextAreaElement | null>(null); const newValues = [...values];
newValues[index] = event.target.value;
onValuesChange(newValues);
};
function handleEditorChange(event: React.ChangeEvent<HTMLTextAreaElement>) { const handleDeleteQuestion = (index: number) => () => {
const text = event.target.value; const newValues = values.filter((_, i) => i !== index); // Remove the question at the specified index
setValue(text); onValuesChange(newValues);
onEditorChange(text || ''); };
}
return ( return (
<label> <div>
<h4>{label}</h4> {/* Label with increased margin */}
<TextareaAutosize <Typography variant="h6" fontWeight="bold" style={{ marginBottom: '24px' }}>
id="editor-textarea" {label}
ref={editorRef} </Typography>
onChange={handleEditorChange}
{/* Map through each question */}
{values.map((value, index) => (
<Box key={index} style={{ marginBottom: '24px' }}>
{/* Bold "Question #" title */}
<Box display="flex" alignItems="center" justifyContent="space-between">
<Typography variant="subtitle1" fontWeight="bold" style={{ marginBottom: '8px' }}>
Question {index + 1}
</Typography>
{/* Delete button */}
<IconButton
onClick={handleDeleteQuestion(index)}
aria-label="delete"
sx={{ color: 'light-gray',
'&:hover': {
color: 'red'
},
}}
>
<DeleteIcon />
</IconButton>
</Box>
{/* TextField for the question */}
<TextField
value={value} value={value}
className="editor" onChange={handleChange(index)}
minRows={5} fullWidth
multiline
minRows={4}
maxRows={Infinity}
variant="outlined"
style={{ overflow: 'auto'}}
/> />
</label>
</Box>
))}
</div>
); );
}; };

View file

@ -29,7 +29,7 @@ const QuizForm: React.FC = () => {
const [filteredValue, setFilteredValue] = useState<string[]>([]); const [filteredValue, setFilteredValue] = useState<string[]>([]);
const { id } = useParams<EditQuizParams>(); const { id } = useParams<EditQuizParams>();
const [value, setValue] = useState(''); const [values, setValues] = useState<string[]>([]);
const [isNewQuiz, setNewQuiz] = useState(false); const [isNewQuiz, setNewQuiz] = useState(false);
const [quiz, setQuiz] = useState<QuizType | null>(null); const [quiz, setQuiz] = useState<QuizType | null>(null);
const navigate = useNavigate(); const navigate = useNavigate();
@ -101,7 +101,7 @@ const QuizForm: React.FC = () => {
setQuizTitle(title); setQuizTitle(title);
setSelectedFolder(folderId); setSelectedFolder(folderId);
setFilteredValue(content); setFilteredValue(content);
setValue(quiz.content.join('\n\n')); setValues(content);
} catch (error) { } 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`)
@ -113,21 +113,17 @@ const QuizForm: React.FC = () => {
fetchData(); fetchData();
}, [id]); }, [id]);
function handleUpdatePreview(value: string) { const handleAddQuestion = () => {
if (value !== '') { console.log("Adding question");
setValue(value); console.log("Current values:", values); // Log current state
} setValues([...values, '']);
console.log("Updated values:", [...values, '']); // Log new state
};
// split value when there is at least one blank line const handleUpdatePreview = (newValues: string[]) => {
const linesArray = value.split(/\n{2,}/); setValues(newValues);
setFilteredValue(newValues.filter(value => value.trim() !== ''));
// if the first item in linesArray is blank, remove it };
if (linesArray[0] === '') linesArray.shift();
if (linesArray[linesArray.length - 1] === '') linesArray.pop();
setFilteredValue(linesArray);
}
const handleQuizTitleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleQuizTitleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setQuizTitle(event.target.value); setQuizTitle(event.target.value);
@ -204,6 +200,8 @@ const QuizForm: React.FC = () => {
navigator.clipboard.writeText(link); navigator.clipboard.writeText(link);
} }
return ( return (
<div className='quizEditor'> <div className='quizEditor'>
@ -213,7 +211,7 @@ const QuizForm: React.FC = () => {
message={`Êtes-vous sûr de vouloir quitter l'éditeur sans sauvegarder le questionnaire?`} message={`Êtes-vous sûr de vouloir quitter l'éditeur sans sauvegarder le questionnaire?`}
/> />
<div className='title'>Éditeur de quiz</div> <div className='title'>Éditeur de Quiz</div>
<div className='dumb'></div> <div className='dumb'></div>
</div> </div>
@ -253,9 +251,12 @@ const QuizForm: React.FC = () => {
<div className='edit'> <div className='edit'>
<Editor <Editor
label="Contenu GIFT du quiz:" label="Contenu GIFT de chaque question:"
initialValue={value} values={values}
onEditorChange={handleUpdatePreview} /> onValuesChange={handleUpdatePreview} />
<Button variant="contained" onClick={handleAddQuestion}>
Ajouter une question
</Button>
<div className='images'> <div className='images'>
<div className='upload'> <div className='upload'>