mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-04 03:31:28 +00:00
chore: application prettier
This commit is contained in:
@ -1,4 +1,13 @@
|
||||
import { Trash2, Edit3, Plus, ZoomIn, Users, Check, X, Hand } from 'lucide-react';
|
||||
import {
|
||||
Trash2,
|
||||
Edit3,
|
||||
Plus,
|
||||
ZoomIn,
|
||||
Users,
|
||||
Check,
|
||||
X,
|
||||
Hand,
|
||||
} from 'lucide-react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Table from '@/components/Table';
|
||||
import Popup from '@/components/Popup';
|
||||
@ -17,30 +26,40 @@ const ItemTypes = {
|
||||
TEACHER: 'teacher',
|
||||
};
|
||||
|
||||
const TeachersDropZone = ({ classe, handleTeachersChange, teachers, isEditing }) => {
|
||||
const [localTeachers, setLocalTeachers] = useState(classe.teachers_details || []);
|
||||
const TeachersDropZone = ({
|
||||
classe,
|
||||
handleTeachersChange,
|
||||
teachers,
|
||||
isEditing,
|
||||
}) => {
|
||||
const [localTeachers, setLocalTeachers] = useState(
|
||||
classe.teachers_details || []
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
}, [teachers]);
|
||||
useEffect(() => {}, [teachers]);
|
||||
|
||||
useEffect(() => {
|
||||
setLocalTeachers(classe.teachers_details || []);
|
||||
}, [classe.teachers_details]);
|
||||
|
||||
useEffect(() => {
|
||||
handleTeachersChange(localTeachers.map(teacher => teacher.id));
|
||||
handleTeachersChange(localTeachers.map((teacher) => teacher.id));
|
||||
}, [localTeachers]);
|
||||
|
||||
const [{ isOver, canDrop }, drop] = useDrop({
|
||||
accept: ItemTypes.TEACHER,
|
||||
drop: (item) => {
|
||||
const teacherDetails = teachers.find(teacher => teacher.id === item.id);
|
||||
const exists = localTeachers.some(teacher => teacher.id === item.id);
|
||||
const teacherDetails = teachers.find((teacher) => teacher.id === item.id);
|
||||
const exists = localTeachers.some((teacher) => teacher.id === item.id);
|
||||
if (!exists) {
|
||||
setLocalTeachers(prevTeachers => {
|
||||
setLocalTeachers((prevTeachers) => {
|
||||
const updatedTeachers = [
|
||||
...prevTeachers,
|
||||
{ id: item.id, last_name: teacherDetails.last_name, first_name: teacherDetails.first_name }
|
||||
{
|
||||
id: item.id,
|
||||
last_name: teacherDetails.last_name,
|
||||
first_name: teacherDetails.first_name,
|
||||
},
|
||||
];
|
||||
return updatedTeachers;
|
||||
});
|
||||
@ -56,26 +75,33 @@ const TeachersDropZone = ({ classe, handleTeachersChange, teachers, isEditing })
|
||||
});
|
||||
|
||||
const handleRemoveTeacher = (id) => {
|
||||
setLocalTeachers(prevTeachers => {
|
||||
const updatedTeachers = prevTeachers.filter(teacher => teacher.id !== id);
|
||||
setLocalTeachers((prevTeachers) => {
|
||||
const updatedTeachers = prevTeachers.filter(
|
||||
(teacher) => teacher.id !== id
|
||||
);
|
||||
return updatedTeachers;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={drop} className={`p-2 rounded-md flex flex-col items-center ${isEditing ? 'border-2 border-dashed border-blue-500 bg-blue-50' : ''} ${
|
||||
isOver && canDrop ? 'border-2 border-solid border-blue-300' : ''
|
||||
}`}
|
||||
<div
|
||||
ref={drop}
|
||||
className={`p-2 rounded-md flex flex-col items-center ${isEditing ? 'border-2 border-dashed border-blue-500 bg-blue-50' : ''} ${
|
||||
isOver && canDrop ? 'border-2 border-solid border-blue-300' : ''
|
||||
}`}
|
||||
>
|
||||
{isEditing && (
|
||||
{isEditing && (
|
||||
<div className="mb-2 text-blue-500 font-semibold flex items-center space-x-2">
|
||||
<Hand className="w-5 h-5" /> {/* Ajoutez l'icône Hand */}
|
||||
<span>Déposez un enseignant ici</span>
|
||||
</div>
|
||||
)}
|
||||
{localTeachers.map((teacher, index) => (
|
||||
<div key={`${teacher.id}-${index}`} className="flex items-center space-x-2 mb-2">
|
||||
<TeacherItem key={teacher.id} teacher={teacher} isDraggable={false}/>
|
||||
<div
|
||||
key={`${teacher.id}-${index}`}
|
||||
className="flex items-center space-x-2 mb-2"
|
||||
>
|
||||
<TeacherItem key={teacher.id} teacher={teacher} isDraggable={false} />
|
||||
{isEditing && (
|
||||
<button
|
||||
type="button"
|
||||
@ -91,15 +117,22 @@ const TeachersDropZone = ({ classe, handleTeachersChange, teachers, isEditing })
|
||||
);
|
||||
};
|
||||
|
||||
const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdit, handleDelete }) => {
|
||||
const ClassesSection = ({
|
||||
classes,
|
||||
setClasses,
|
||||
teachers,
|
||||
handleCreate,
|
||||
handleEdit,
|
||||
handleDelete,
|
||||
}) => {
|
||||
const [formData, setFormData] = useState({});
|
||||
const [editingClass, setEditingClass] = useState(null);
|
||||
const [newClass, setNewClass] = useState(null);
|
||||
const [localErrors, setLocalErrors] = useState({});
|
||||
const [popupVisible, setPopupVisible] = useState(false);
|
||||
const [popupMessage, setPopupMessage] = useState("");
|
||||
const [popupMessage, setPopupMessage] = useState('');
|
||||
const [removePopupVisible, setRemovePopupVisible] = useState(false);
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState("");
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState('');
|
||||
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
|
||||
const [detailsModalVisible, setDetailsModalVisible] = useState(false);
|
||||
const [selectedClass, setSelectedClass] = useState(null);
|
||||
@ -122,11 +155,15 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
{ id: 9, name: 'CM2', age: 10 },
|
||||
];
|
||||
|
||||
const allNiveaux = [...niveauxPremierCycle, ...niveauxSecondCycle, ...niveauxTroisiemeCycle];
|
||||
const allNiveaux = [
|
||||
...niveauxPremierCycle,
|
||||
...niveauxSecondCycle,
|
||||
...niveauxTroisiemeCycle,
|
||||
];
|
||||
|
||||
const getNiveauxLabels = (levels) => {
|
||||
return levels.map(niveauId => {
|
||||
const niveau = allNiveaux.find(n => n.id === niveauId);
|
||||
return levels.map((niveauId) => {
|
||||
const niveau = allNiveaux.find((n) => n.id === niveauId);
|
||||
return niveau ? niveau.name : niveauId;
|
||||
});
|
||||
};
|
||||
@ -143,7 +180,10 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
const choices = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const year = startYear + i;
|
||||
choices.push({ value: `${year}-${year + 1}`, label: `${year}-${year + 1}` });
|
||||
choices.push({
|
||||
value: `${year}-${year + 1}`,
|
||||
label: `${year}-${year + 1}`,
|
||||
});
|
||||
}
|
||||
return choices;
|
||||
};
|
||||
@ -154,8 +194,25 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
};
|
||||
|
||||
const handleAddClass = () => {
|
||||
setNewClass({ id: Date.now(), atmosphere_name: '', age_range: '', levels: [], number_of_students: '', school_year: '', teachers: [], establishment: ESTABLISHMENT_ID });
|
||||
setFormData({ atmosphere_name: '', age_range: '', levels: [], number_of_students: '', school_year: '', teachers: [], establishment: ESTABLISHMENT_ID });
|
||||
setNewClass({
|
||||
id: Date.now(),
|
||||
atmosphere_name: '',
|
||||
age_range: '',
|
||||
levels: [],
|
||||
number_of_students: '',
|
||||
school_year: '',
|
||||
teachers: [],
|
||||
establishment: ESTABLISHMENT_ID,
|
||||
});
|
||||
setFormData({
|
||||
atmosphere_name: '',
|
||||
age_range: '',
|
||||
levels: [],
|
||||
number_of_students: '',
|
||||
school_year: '',
|
||||
teachers: [],
|
||||
establishment: ESTABLISHMENT_ID,
|
||||
});
|
||||
};
|
||||
|
||||
const handleChange = (e) => {
|
||||
@ -175,7 +232,13 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
};
|
||||
|
||||
const handleSaveNewClass = () => {
|
||||
if (newClass.atmosphere_name && newClass.age_range && newClass.levels.length > 0 && newClass.number_of_students && newClass.school_year) {
|
||||
if (
|
||||
newClass.atmosphere_name &&
|
||||
newClass.age_range &&
|
||||
newClass.levels.length > 0 &&
|
||||
newClass.number_of_students &&
|
||||
newClass.school_year
|
||||
) {
|
||||
handleCreate(newClass)
|
||||
.then((createdClass) => {
|
||||
setClasses((prevClasses) => [createdClass, ...classes]);
|
||||
@ -185,21 +248,31 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
.catch((error) => {
|
||||
logger.error('Error:', error.message);
|
||||
if (error.details) {
|
||||
logger.error('Form errors:', error.details);
|
||||
setLocalErrors(error.details);
|
||||
logger.error('Form errors:', error.details);
|
||||
setLocalErrors(error.details);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setPopupMessage("Tous les champs doivent être remplis et valides");
|
||||
setPopupVisible(true);
|
||||
}
|
||||
} else {
|
||||
setPopupMessage('Tous les champs doivent être remplis et valides');
|
||||
setPopupVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateClass = (id, updatedData) => {
|
||||
if (updatedData.atmosphere_name && updatedData.age_range && updatedData.levels.length > 0 && updatedData.number_of_students && updatedData.school_year) {
|
||||
if (
|
||||
updatedData.atmosphere_name &&
|
||||
updatedData.age_range &&
|
||||
updatedData.levels.length > 0 &&
|
||||
updatedData.number_of_students &&
|
||||
updatedData.school_year
|
||||
) {
|
||||
handleEdit(id, updatedData)
|
||||
.then((updatedClass) => {
|
||||
setClasses((prevClasses) => prevClasses.map((classe) => (classe.id === id ? updatedClass : classe)));
|
||||
setClasses((prevClasses) =>
|
||||
prevClasses.map((classe) =>
|
||||
classe.id === id ? updatedClass : classe
|
||||
)
|
||||
);
|
||||
setEditingClass(null);
|
||||
setFormData({});
|
||||
setLocalErrors({});
|
||||
@ -207,12 +280,12 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
.catch((error) => {
|
||||
logger.error('Error:', error.message);
|
||||
if (error.details) {
|
||||
logger.error('Form errors:', error.details);
|
||||
setLocalErrors(error.details);
|
||||
logger.error('Form errors:', error.details);
|
||||
setLocalErrors(error.details);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setPopupMessage("Tous les champs doivent être remplis et valides");
|
||||
setPopupMessage('Tous les champs doivent être remplis et valides');
|
||||
setPopupVisible(true);
|
||||
}
|
||||
};
|
||||
@ -236,7 +309,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
};
|
||||
|
||||
const handleMultiSelectChange = (selectedOptions) => {
|
||||
const levels = selectedOptions.map(option => option.id);
|
||||
const levels = selectedOptions.map((option) => option.id);
|
||||
|
||||
if (editingClass) {
|
||||
setFormData((prevData) => ({
|
||||
@ -277,7 +350,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
errorMsg={getError('atmosphere_name')}
|
||||
/>
|
||||
);
|
||||
case 'TRANCHE D\'AGE':
|
||||
case "TRANCHE D'AGE":
|
||||
return (
|
||||
<InputText
|
||||
name="age_range"
|
||||
@ -286,14 +359,20 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
placeholder="Tranche d'âge (ex: 3-6)"
|
||||
errorMsg={getError('age_range')}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'NIVEAUX':
|
||||
return (
|
||||
<MultiSelect
|
||||
name="levels"
|
||||
label="Sélection de niveaux"
|
||||
options={allNiveaux}
|
||||
selectedOptions={currentData.levels ? currentData.levels.map(levelId => allNiveaux.find(level => level.id === levelId)) : []}
|
||||
selectedOptions={
|
||||
currentData.levels
|
||||
? currentData.levels.map((levelId) =>
|
||||
allNiveaux.find((level) => level.id === levelId)
|
||||
)
|
||||
: []
|
||||
}
|
||||
onChange={handleMultiSelectChange}
|
||||
errorMsg={getError('levels')}
|
||||
/>
|
||||
@ -308,8 +387,8 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
placeholder="Capacité"
|
||||
errorMsg={getError('number_of_students')}
|
||||
/>
|
||||
)
|
||||
case 'ANNÉE SCOLAIRE' :
|
||||
);
|
||||
case 'ANNÉE SCOLAIRE':
|
||||
return (
|
||||
<SelectChoice
|
||||
type="select"
|
||||
@ -322,24 +401,35 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
IconItem={null}
|
||||
disabled={false}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'ENSEIGNANTS':
|
||||
return (
|
||||
<TeachersDropZone classe={currentData} handleTeachersChange={handleTeachersChange} teachers={teachers} isEditing={isEditing || isCreating} />
|
||||
<TeachersDropZone
|
||||
classe={currentData}
|
||||
handleTeachersChange={handleTeachersChange}
|
||||
teachers={teachers}
|
||||
isEditing={isEditing || isCreating}
|
||||
/>
|
||||
);
|
||||
case 'ACTIONS':
|
||||
return (
|
||||
<div className="flex justify-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => (isEditing ? handleUpdateClass(editingClass, formData) : handleSaveNewClass())}
|
||||
onClick={() =>
|
||||
isEditing
|
||||
? handleUpdateClass(editingClass, formData)
|
||||
: handleSaveNewClass()
|
||||
}
|
||||
className="text-green-500 hover:text-green-700"
|
||||
>
|
||||
<Check className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => (isEditing ? setEditingClass(null) : setNewClass(null))}
|
||||
onClick={() =>
|
||||
isEditing ? setEditingClass(null) : setNewClass(null)
|
||||
}
|
||||
className="text-red-500 hover:text-red-700"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
@ -353,28 +443,34 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
switch (column) {
|
||||
case 'AMBIANCE':
|
||||
return classe.atmosphere_name;
|
||||
case 'TRANCHE D\'AGE':
|
||||
case "TRANCHE D'AGE":
|
||||
return classe.age_range;
|
||||
case 'NIVEAUX':
|
||||
const levelLabels = Array.isArray(classe.levels) ? getNiveauxLabels(classe.levels) : [];
|
||||
const levelLabels = Array.isArray(classe.levels)
|
||||
? getNiveauxLabels(classe.levels)
|
||||
: [];
|
||||
return (
|
||||
<div className="flex flex-wrap justify-center items-center space-x-2">
|
||||
{levelLabels.length > 0
|
||||
? levelLabels.map((label, index) => (
|
||||
<LevelLabel key={index} label={label} index={index} />
|
||||
))
|
||||
: 'Aucun niveau'}
|
||||
? levelLabels.map((label, index) => (
|
||||
<LevelLabel key={index} label={label} index={index} />
|
||||
))
|
||||
: 'Aucun niveau'}
|
||||
</div>
|
||||
);
|
||||
case 'CAPACITE':
|
||||
return classe.number_of_students;
|
||||
case 'ANNÉE SCOLAIRE' :
|
||||
case 'ANNÉE SCOLAIRE':
|
||||
return classe.school_year;
|
||||
case 'ENSEIGNANTS':
|
||||
return (
|
||||
<div className="flex justify-center space-x-2 flex-wrap">
|
||||
{classe.teachers_details.map((teacher) => (
|
||||
<TeacherItem key={teacher.id} teacher={teacher} isDraggable={false} />
|
||||
<TeacherItem
|
||||
key={teacher.id}
|
||||
teacher={teacher}
|
||||
isDraggable={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@ -385,7 +481,9 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
<div className="flex justify-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setEditingClass(classe.id) || setFormData(classe)}
|
||||
onClick={() =>
|
||||
setEditingClass(classe.id) || setFormData(classe)
|
||||
}
|
||||
className="text-blue-500 hover:text-blue-700"
|
||||
>
|
||||
<Edit3 className="w-5 h-5" />
|
||||
@ -394,18 +492,29 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setRemovePopupVisible(true);
|
||||
setRemovePopupMessage("Attentions ! \nVous êtes sur le point de supprimer la classe " + classe.atmosphere_name + ".\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?");
|
||||
setRemovePopupMessage(
|
||||
'Attentions ! \nVous êtes sur le point de supprimer la classe ' +
|
||||
classe.atmosphere_name +
|
||||
".\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?"
|
||||
);
|
||||
setRemovePopupOnConfirm(() => () => {
|
||||
handleDelete(classe.id)
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
logger.debug('Success:', data);
|
||||
setPopupMessage("La classe " + classe.atmosphere_name + " a été correctement supprimée");
|
||||
setPopupMessage(
|
||||
'La classe ' +
|
||||
classe.atmosphere_name +
|
||||
' a été correctement supprimée'
|
||||
);
|
||||
setPopupVisible(true);
|
||||
setRemovePopupVisible(false);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Error archiving data:', error);
|
||||
setPopupMessage("Erreur lors de la suppression de la classe " + classe.atmosphere_name);
|
||||
setPopupMessage(
|
||||
'Erreur lors de la suppression de la classe ' +
|
||||
classe.atmosphere_name
|
||||
);
|
||||
setPopupVisible(true);
|
||||
setRemovePopupVisible(false);
|
||||
});
|
||||
@ -431,14 +540,14 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ name: 'AMBIANCE', label: 'Nom d\'ambiance' },
|
||||
{ name: 'TRANCHE D\'AGE', label: 'Tranche d\'âge' },
|
||||
{ name: 'AMBIANCE', label: "Nom d'ambiance" },
|
||||
{ name: "TRANCHE D'AGE", label: "Tranche d'âge" },
|
||||
{ name: 'NIVEAUX', label: 'Niveaux' },
|
||||
{ name: 'CAPACITE', label: 'Capacité max' },
|
||||
{ name: 'ANNÉE SCOLAIRE', label: 'Année scolaire' },
|
||||
{ name: 'ENSEIGNANTS', label: 'Enseignants' },
|
||||
{ name: 'MISE A JOUR', label: 'Date mise à jour' },
|
||||
{ name: 'ACTIONS', label: 'Actions' }
|
||||
{ name: 'ACTIONS', label: 'Actions' },
|
||||
];
|
||||
|
||||
return (
|
||||
@ -449,7 +558,11 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
<Users className="w-6 h-6 text-emerald-500 mr-2" />
|
||||
<h2 className="text-xl font-semibold">Classes</h2>
|
||||
</div>
|
||||
<button type="button" onClick={handleAddClass} className="text-emerald-500 hover:text-emerald-700">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleAddClass}
|
||||
className="text-emerald-500 hover:text-emerald-700"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
@ -460,7 +573,9 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
/>
|
||||
<Popup
|
||||
visible={detailsModalVisible}
|
||||
message={selectedClass ? <ClasseDetails classe={selectedClass} /> : null}
|
||||
message={
|
||||
selectedClass ? <ClasseDetails classe={selectedClass} /> : null
|
||||
}
|
||||
onConfirm={() => setDetailsModalVisible(false)}
|
||||
onCancel={() => setDetailsModalVisible(false)}
|
||||
uniqueConfirmButton={true}
|
||||
@ -483,4 +598,4 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi
|
||||
);
|
||||
};
|
||||
|
||||
export default ClassesSection;
|
||||
export default ClassesSection;
|
||||
|
||||
Reference in New Issue
Block a user