import { Trash2, Edit3, ZoomIn, Users, Check, X, Hand } from 'lucide-react'; import React, { useState, useEffect } from 'react'; import Table from '@/components/Table'; import Popup from '@/components/Popup'; import InputText from '@/components/Form/InputText'; import SelectChoice from '@/components/Form/SelectChoice'; import TeacherItem from '@/components/Structure/Configuration/TeacherItem'; import MultiSelect from '@/components/Form/MultiSelect'; import LevelLabel from '@/components/CustomLabels/LevelLabel'; import { DndProvider, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import logger from '@/utils/logger'; import SectionHeader from '@/components/SectionHeader'; import { useEstablishment } from '@/context/EstablishmentContext'; import { FE_ADMIN_STRUCTURE_SCHOOLCLASS_MANAGEMENT_URL } from '@/utils/Url'; import { usePlanning } from '@/context/PlanningContext'; import { useClasses } from '@/context/ClassesContext'; import { useRouter } from 'next/navigation'; import AlertMessage from '@/components/AlertMessage'; const ItemTypes = { TEACHER: 'teacher', }; const TeachersDropZone = ({ classe, handleTeachersChange, teachers, isEditing, }) => { const [localTeachers, setLocalTeachers] = useState( classe.teachers_details || [] ); useEffect(() => {}, [teachers]); useEffect(() => { setLocalTeachers(classe.teachers_details || []); }, [classe.teachers_details]); useEffect(() => { 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); if (!exists) { setLocalTeachers((prevTeachers) => { const updatedTeachers = [ ...prevTeachers, { id: item.id, last_name: teacherDetails.last_name, first_name: teacherDetails.first_name, }, ]; return updatedTeachers; }); } }, collect: (monitor) => ({ isOver: !!monitor.isOver(), canDrop: !!monitor.canDrop(), }), canDrop: () => { return isEditing; }, }); const handleRemoveTeacher = (id) => { setLocalTeachers((prevTeachers) => { const updatedTeachers = prevTeachers.filter( (teacher) => teacher.id !== id ); return updatedTeachers; }); }; return (
{isEditing && (
{/* Ajoutez l'icône Hand */} Déposez un enseignant ici
)} {localTeachers.map((teacher, index) => (
{isEditing && ( )}
))}
); }; 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 [removePopupVisible, setRemovePopupVisible] = useState(false); const [removePopupMessage, setRemovePopupMessage] = useState(''); const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {}); const { selectedEstablishmentId, profileRole } = useEstablishment(); const { addSchedule, reloadPlanning, reloadEvents } = usePlanning(); const { getNiveauxLabels, allNiveaux } = useClasses(); const router = useRouter(); // Fonction pour générer les années scolaires const getSchoolYearChoices = () => { const currentDate = new Date(); const currentYear = currentDate.getFullYear(); const currentMonth = currentDate.getMonth() + 1; // Les mois sont indexés à partir de 0 // Si nous sommes avant septembre, l'année scolaire en cours a commencé l'année précédente const startYear = currentMonth >= 9 ? currentYear : currentYear - 1; const choices = []; for (let i = 0; i < 3; i++) { const year = startYear + i; choices.push({ value: `${year}-${year + 1}`, label: `${year}-${year + 1}`, }); } return choices; }; // Récupération des messages d'erreur const getError = (field) => { return localErrors?.[field]?.[0]; }; const handleAddClass = () => { setNewClass({ id: Date.now(), atmosphere_name: '', age_range: '', levels: [], number_of_students: null, school_year: '', teachers: [], establishment: selectedEstablishmentId, }); setFormData({ atmosphere_name: '', age_range: '', levels: [], number_of_students: null, school_year: '', teachers: [], establishment: selectedEstablishmentId, }); }; const handleChange = (e) => { const { name, value } = e.target; if (editingClass) { setFormData((prevData) => ({ ...prevData, [name]: value, })); } else if (newClass) { setNewClass((prevData) => ({ ...prevData, [name]: value, })); } }; const handleSaveNewClass = () => { if ( newClass.atmosphere_name && newClass.levels.length > 0 && newClass.school_year ) { handleCreate(newClass) .then((createdClass) => { setClasses((prevClasses) => [createdClass, ...classes]); setNewClass(null); setLocalErrors({}); // Creation des plannings associé à la classe createdClass.levels.forEach((level) => { const levelName = allNiveaux.find((lvl) => lvl.id === level)?.name; const planningName = `${createdClass.atmosphere_name} - ${levelName}`; const newPlanning = { name: planningName, color: '#FF5733', // Couleur par défaut school_class: createdClass.id, }; addSchedule(newPlanning); }); }) .catch((error) => { logger.error('Error:', error.message); if (error.details) { logger.error('Form errors:', error.details); setLocalErrors(error.details); } }); } else { setPopupMessage('Tous les champs doivent être remplis et valides'); setPopupVisible(true); } }; const handleUpdateClass = (id, updatedData) => { if ( updatedData.atmosphere_name && updatedData.levels.length > 0 && updatedData.school_year ) { handleEdit(id, updatedData) .then((updatedClass) => { setClasses((prevClasses) => prevClasses.map((classe) => classe.id === id ? updatedClass : classe ) ); setEditingClass(null); setFormData({}); setLocalErrors({}); }) .catch((error) => { logger.error('Error:', error.message); if (error.details) { logger.error('Form errors:', error.details); setLocalErrors(error.details); } }); } else { setPopupMessage('Tous les champs doivent être remplis et valides'); setPopupVisible(true); } }; const handleTeachersChange = (selectedTeachers) => { if (editingClass) { setFormData((prevData) => ({ ...prevData, teachers: selectedTeachers, })); } else if (newClass) { setNewClass((prevData) => ({ ...prevData, teachers: selectedTeachers, })); setFormData((prevData) => ({ ...prevData, teachers: selectedTeachers, })); } }; const handleMultiSelectChange = (selectedOptions) => { const levels = selectedOptions.map((option) => option.id); if (editingClass) { setFormData((prevData) => ({ ...prevData, levels, })); } else if (newClass) { setNewClass((prevData) => ({ ...prevData, levels, })); setFormData((prevData) => ({ ...prevData, levels, })); } }; const renderClassCell = (classe, column) => { const isEditing = editingClass === classe.id; const isCreating = newClass && newClass.id === classe.id; const currentData = isEditing ? formData : newClass || {}; if (isEditing || isCreating) { switch (column) { case 'AMBIANCE': return ( ); case "TRANCHE D'AGE": return ( ); case 'NIVEAUX': return ( allNiveaux.find((level) => level.id === levelId) ) : [] } onChange={handleMultiSelectChange} errorMsg={getError('levels')} /> ); case 'CAPACITE': return ( ); case 'ANNÉE SCOLAIRE': return ( ); case 'ENSEIGNANTS': return ( ); case 'ACTIONS': return (
); default: return null; } } else { switch (column) { case 'AMBIANCE': return classe.atmosphere_name; case "TRANCHE D'AGE": return classe.age_range; case 'NIVEAUX': const levelLabels = Array.isArray(classe.levels) ? getNiveauxLabels(classe.levels.sort((a, b) => a - b)) // Trier les niveaux par ordre croissant : []; return (
{levelLabels.length > 0 ? levelLabels.map((label, index) => ( )) : 'Aucun niveau'}
); case 'CAPACITE': return classe.number_of_students; case 'ANNÉE SCOLAIRE': return classe.school_year; case 'ENSEIGNANTS': return (
{classe.teachers_details.map((teacher) => ( ))}
); case 'MISE A JOUR': return classe.updated_date_formatted; case 'ACTIONS': // Affichage des actions en mode affichage (hors édition/création) if (profileRole === 0) { // Si professeur, uniquement le bouton ZoomIn return (
); } // Sinon, toutes les actions (admin) return (
); default: return null; } } }; const columns = [ { 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' }, ]; return (
} /> setPopupVisible(false)} onCancel={() => setPopupVisible(false)} uniqueConfirmButton={true} /> setRemovePopupVisible(false)} /> ); }; export default ClassesSection;