Affichage des noms des collaborateurs en congé dans le calendrier.

Ajout du champ "Autre" dans le formulaire de demande de congé.
Mise en place de l’export du calendrier aux formats ICS et CSV.
This commit is contained in:
2025-08-06 16:49:31 +02:00
parent 238a7a31b0
commit fbcd80fb6f
3 changed files with 230 additions and 15 deletions

View File

@@ -24,6 +24,8 @@ const NewLeaveRequestModal = ({
const [error, setError] = useState('');
const [calculatedDays, setCalculatedDays] = useState(0);
const [isPreselected, setIsPreselected] = useState(false);
const [isOtherChecked, setIsOtherChecked] = useState(false);
const [otherLeaveType, setOtherLeaveType] = useState('');
// Vérifier si des valeurs sont pré-sélectionnées
useEffect(() => {
@@ -130,8 +132,36 @@ const NewLeaveRequestModal = ({
return { ...prev, types: newTypes };
});
setError('');
// Désélectionner le type "Autre" si un autre type est sélectionné
if (type !== 'Autres') {
setIsOtherChecked(false);
setOtherLeaveType('');
}
};
const handleOtherCheckboxChange = (e) => {
const isChecked = e.target.checked;
setIsOtherChecked(isChecked);
// Si la case est cochée, désélectionner les autres types
if (isChecked) {
setFormData(prev => ({ ...prev, types: ['Autres'] }));
} else {
// Si elle est décochée, vider le type et les documents
setOtherLeaveType('');
setFormData(prev => ({ ...prev, types: [] }));
}
setError('');
};
const handleOtherTypeChange = (e) => {
setOtherLeaveType(e.target.value);
setFormData(prev => ({ ...prev, types: [e.target.value] }));
};
const handleDistributionChange = (type, days) => {
setTypeDistribution(prev => ({
...prev,
@@ -183,6 +213,12 @@ const NewLeaveRequestModal = ({
setError('Impossible de faire une demande pour une date passée');
return false;
}
// Vérification de la sélection d'un type "autre"
if (isOtherChecked && !otherLeaveType) {
setError('Veuillez sélectionner un type de congé dans la liste "Autre"');
return false;
}
// Vérification de la distribution des jours
if (formData.types.length > 1) {
@@ -197,6 +233,12 @@ const NewLeaveRequestModal = ({
for (const type of formData.types) {
const requiredDays = formData.types.length > 1 ? (typeDistribution[type] || 0) : calculatedDays;
// Les types "autres" n'ont pas de solde à vérifier
const nonSoldeTypes = ['Récup', 'Congés sans solde', 'Congés pour évènement familial', 'Congé maternité', 'Congé paternité', 'Congé parental', 'Congé parental à temps partiel', 'Autres'];
if (nonSoldeTypes.includes(type)) {
continue;
}
if (type === 'CP' && requiredDays > availableLeaveCounters.availableCP) {
setError(`Solde CP insuffisant. Vous avez ${availableLeaveCounters.availableCP} jours disponibles`);
return false;
@@ -223,6 +265,8 @@ const NewLeaveRequestModal = ({
// Créer une demande pour chaque type de congé
const requests = formData.types.map(type => {
const days = formData.types.length > 1 ? (typeDistribution[type] || 0) : calculatedDays;
// Utiliser le type sélectionné dans la liste déroulante si "Autre" est coché
const finalType = type === 'Autres' ? otherLeaveType : type;
return {
EmployeeId: userId,
TypeConge: type,
@@ -325,6 +369,7 @@ const NewLeaveRequestModal = ({
)}
{/* Type de congé */}
<div>
<label className="block text-sm lg:text-base font-medium text-gray-700 mb-2">
Types de congé * {formData.types.length > 0 && `(${formData.types.length} sélectionné${formData.types.length > 1 ? 's' : ''})`}
@@ -341,7 +386,7 @@ const NewLeaveRequestModal = ({
type="checkbox"
checked={formData.types.includes(type.key)}
onChange={() => handleTypeToggle(type.key)}
disabled={isPreselected && preselectedType && preselectedType !== type.key}
disabled={isPreselected && preselectedType && preselectedType !== type.key || isOtherChecked}
className="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
/>
<span className={`px-2 lg:px-3 py-1 rounded-full text-xs lg:text-sm font-medium border ${getTypeColor(type.key)}`}>
@@ -350,8 +395,46 @@ const NewLeaveRequestModal = ({
</label>
</div>
))}
{/* Nouvelle case à cocher pour "Autre" */}
<div className="flex items-center gap-3">
<label className="flex items-center gap-2 cursor-pointer flex-1">
<input
type="checkbox"
checked={isOtherChecked}
onChange={handleOtherCheckboxChange}
className="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
/>
<span className={`px-2 lg:px-3 py-1 rounded-full text-xs lg:text-sm font-medium border ${getTypeColor('Autres')}`}>
Autre
</span>
</label>
</div>
{/* Liste déroulante "Autre" conditionnelle */}
{isOtherChecked && (
<div className="mt-2 pl-6">
<label className="block text-sm font-medium text-gray-700 mb-1">
Sélectionnez le type de congé
</label>
<select
value={otherLeaveType}
onChange={handleOtherTypeChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm"
required
>
<option value="">-- Choisir un type --</option>
<option value="Récup">Récup</option>
<option value="Congés sans solde">Congés sans solde</option>
<option value="Congés pour évènement familial">Congés pour évènement familial</option>
<option value="Congé maternité">Congé maternité</option>
<option value="Congé paternité">Congé paternité</option>
<option value="Congé parental">Congé parental</option>
<option value="Congé parental à temps partiel">Congé parental à temps partiel</option>
</select>
</div>
)}
</div>
</div>
{/* Distribution des jours si plusieurs types sélectionnés */}
{formData.types.length > 1 && calculatedDays > 0 && (