import React, { useState, useEffect } from 'react';
import { Edit3, Trash2, GraduationCap, Check, X, Hand } from 'lucide-react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
import ToggleSwitch from '@/components/Form/ToggleSwitch';
import { useCsrfToken } from '@/context/CsrfContext';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import InputText from '@/components/Form/InputText';
import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem';
import TeacherItem from './TeacherItem';
import logger from '@/utils/logger';
import { useEstablishment } from '@/context/EstablishmentContext';
import SectionHeader from '@/components/SectionHeader';
import AlertMessage from '@/components/AlertMessage';
const ItemTypes = {
SPECIALITY: 'speciality',
};
const SpecialitiesDropZone = ({
teacher,
handleSpecialitiesChange,
specialities,
isEditing,
}) => {
const [localSpecialities, setLocalSpecialities] = useState(
teacher.specialities_details || []
);
useEffect(() => {}, [specialities]);
useEffect(() => {
setLocalSpecialities(teacher.specialities_details || []);
}, [teacher.specialities_details]);
useEffect(() => {
handleSpecialitiesChange(
localSpecialities.map((speciality) => speciality.id)
);
}, [localSpecialities]);
const [{ isOver, canDrop }, drop] = useDrop({
accept: ItemTypes.SPECIALITY,
drop: (item) => {
const specialityDetails = specialities.find(
(speciality) => speciality.id === item.id
);
const exists = localSpecialities.some(
(speciality) => speciality.id === item.id
);
if (!exists) {
setLocalSpecialities((prevSpecialities) => {
const updatedSpecialities = [
...prevSpecialities,
{
id: item.id,
name: specialityDetails.name,
color_code: specialityDetails.color_code,
},
];
return updatedSpecialities;
});
}
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
canDrop: !!monitor.canDrop(),
}),
canDrop: () => {
return isEditing;
},
});
const handleRemoveSpeciality = (id) => {
setLocalSpecialities((prevSpecialities) => {
const updatedSpecialities = prevSpecialities.filter(
(speciality) => speciality.id !== id
);
return updatedSpecialities;
});
};
return (
{isEditing && (
{/* Ajoutez l'icône Hand */}
Déposez une spécialité ici
)}
{localSpecialities.map((speciality, index) => (
{isEditing && (
)}
))}
);
};
const TeachersSection = ({
teachers,
setTeachers,
specialities,
profiles,
handleCreate,
handleEdit,
handleDelete,
}) => {
const csrfToken = useCsrfToken();
const [editingTeacher, setEditingTeacher] = useState(null);
const [newTeacher, setNewTeacher] = useState(null);
const [formData, setFormData] = useState({});
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 } = useEstablishment();
// --- UTILS ---
// Retourne le profil existant pour un email
const getUsedProfileForEmail = (email) => {
// On cherche tous les profils dont l'email correspond
const matchingProfiles = profiles.filter(p => p.email === email);
// On retourne le premier profil correspondant (ou undefined)
const result = matchingProfiles.length > 0 ? matchingProfiles[0] : undefined;
return result;
};
// Met à jour le formData et newTeacher si besoin
const updateFormData = (data) => {
setFormData(prev => ({ ...prev, ...data }));
if (newTeacher) setNewTeacher(prev => ({ ...prev, ...data }));
};
// Récupération des messages d'erreur pour un champ donné
const getError = (field) => {
return localErrors?.[field]?.[0];
};
// --- HANDLERS ---
const handleEmailChange = (e) => {
const email = e.target.value;
const existingProfile = getUsedProfileForEmail(email);
if (existingProfile) {
logger.info(`Adresse email déjà utilisée pour le profil ${existingProfile.id}`);
}
updateFormData({
associated_profile_email: email,
existingProfileId: existingProfile ? existingProfile.id : null,
});
};
const handleAddTeacher = () => {
setNewTeacher({
id: Date.now(),
last_name: '',
first_name: '',
associated_profile_email: '',
specialities: [],
role_type: 0,
});
setFormData({
last_name: '',
first_name: '',
associated_profile_email: '',
specialities: [],
role_type: 0,
});
};
const handleRemoveTeacher = (id) => {
logger.debug('[DELETE] Suppression teacher id:', id);
return handleDelete(id)
.then(() => {
setTeachers(prevTeachers =>
prevTeachers.filter(teacher => teacher.id !== id)
);
logger.debug('[DELETE] Teacher supprimé:', id);
})
.catch(logger.error);
};
const handleSaveNewTeacher = () => {
if (
formData.last_name &&
formData.first_name &&
formData.associated_profile_email
) {
const data = {
last_name: formData.last_name,
first_name: formData.first_name,
profile_role_data: {
establishment: selectedEstablishmentId,
role_type: formData.role_type || 0,
is_active: true,
...(formData.existingProfileId
? { profile: formData.existingProfileId }
: {
profile_data: {
email: formData.associated_profile_email,
username: formData.associated_profile_email,
password: 'Provisoire01!',
},
}),
},
specialities: formData.specialities || [],
};
handleCreate(data)
.then((createdTeacher) => {
// Recherche du profile associé dans profiles
let newProfileId = undefined;
let foundProfile = undefined;
if (
createdTeacher &&
createdTeacher.profile_role &&
createdTeacher.profile
) {
newProfileId = createdTeacher.profile;
foundProfile = profiles.find(p => p.id === newProfileId);
}
setTeachers([createdTeacher, ...teachers]);
setNewTeacher(null);
setLocalErrors({});
setFormData(prev => ({
...prev,
existingProfileId: newProfileId,
}));
})
.catch((error) => {
logger.error('Error:', error.message);
if (error.details) setLocalErrors(error.details);
});
} else {
setPopupMessage('Tous les champs doivent être remplis et valides');
setPopupVisible(true);
}
};
const handleUpdateTeacher = (id, updatedData) => {
if (
updatedData.last_name &&
updatedData.first_name &&
updatedData.associated_profile_email
) {
const profileRoleData = {
id: updatedData.profile_role,
establishment: selectedEstablishmentId,
role_type: updatedData.role_type || 0,
profile: updatedData.existingProfileId,
};
handleEdit(id, {
last_name: updatedData.last_name,
first_name: updatedData.first_name,
profile_role_data: profileRoleData,
specialities: updatedData.specialities || [],
})
.then((updatedTeacher) => {
setTeachers((prevTeachers) =>
prevTeachers.map((teacher) =>
teacher.id === id ? { ...teacher, ...updatedTeacher } : teacher
)
);
setEditingTeacher(null);
setFormData({});
})
.catch((error) => {
logger.error('Error:', error.message);
if (error.details) setLocalErrors(error.details);
});
} else {
setPopupMessage('Tous les champs doivent être remplis et valides');
setPopupVisible(true);
}
};
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
let parsedValue = type === 'checkbox' ? (checked ? 1 : 0) : value;
updateFormData({ [name]: parsedValue });
};
const handleSpecialitiesChange = (selectedSpecialities) => {
updateFormData({ specialities: selectedSpecialities });
};
const handleEditTeacher = (teacher) => {
setEditingTeacher(teacher.id);
setFormData({
...teacher,
associated_profile_email: teacher.associated_profile_email,
role_type: teacher.role_type,
});
};
const renderTeacherCell = (teacher, column) => {
const isEditing = editingTeacher === teacher.id;
const isCreating = newTeacher && newTeacher.id === teacher.id;
const currentData = isEditing ? formData : newTeacher;
if (isEditing || isCreating) {
switch (column) {
case 'NOM - PRENOM':
return (
);
case 'EMAIL':
return (
);
case 'SPECIALITES':
return (
);
case 'ADMINISTRATEUR':
return (
);
case 'ACTIONS':
return (
);
default:
return null;
}
} else {
switch (column) {
case 'NOM - PRENOM':
return ;
case 'EMAIL':
return teacher.associated_profile_email;
case 'SPECIALITES':
return (
{teacher.specialities_details.map((speciality) => (
))}
);
case 'ADMINISTRATEUR':
if (teacher.associated_profile_email) {
const badgeClass =
teacher.role_type === 1
? 'bg-red-100 text-red-600'
: 'bg-blue-100 text-blue-600';
const label = teacher.role_type === 1 ? 'OUI' : 'NON';
return (
{label}
);
} else {
return Non définie;
}
case 'MISE A JOUR':
return teacher.updated_date_formatted;
case 'ACTIONS':
return (
);
default:
return null;
}
}
};
const columns = [
{ name: 'NOM - PRENOM', label: 'Nom et prénom' },
{ name: 'EMAIL', label: 'Email' },
{ name: 'SPECIALITES', label: 'Spécialités' },
{ name: 'ADMINISTRATEUR', label: 'Profil' },
{ name: 'MISE A JOUR', label: 'Mise à jour' },
{ name: 'ACTIONS', label: 'Actions' },
];
return (
}
/>
setPopupVisible(false)}
onCancel={() => setPopupVisible(false)}
uniqueConfirmButton={true}
/>
setRemovePopupVisible(false)}
/>
);
};
export default TeachersSection;