Files
MAD-Platform/components/ParticipationEditModal.tsx

181 lines
6.3 KiB
TypeScript
Raw Normal View History

2026-02-15 14:36:28 +01:00
'use client';
import { useState, useEffect } from 'react';
import { useNotification } from './NotificationProvider';
interface Participation {
id: string;
destinataireEmail: string;
destinataireNom: string;
destinataireType: string;
montant: number | null;
complement: string | null;
adherent: { id: string; nom: string; prenom: string; email: string };
trajet: { id: string; date: string; adresseDepart: string; adresseArrivee: string };
}
interface ParticipationEditModalProps {
participation: Participation;
onClose: () => void;
onSuccess: () => void;
}
export default function ParticipationEditModal({
participation,
onClose,
onSuccess,
}: ParticipationEditModalProps) {
const { showNotification } = useNotification();
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState({
destinataireEmail: '',
destinataireNom: '',
destinataireType: 'adherent',
montant: '',
complement: '',
});
useEffect(() => {
setFormData({
destinataireEmail: participation.destinataireEmail,
destinataireNom: participation.destinataireNom,
destinataireType: participation.destinataireType || 'adherent',
montant: participation.montant != null ? String(participation.montant) : '',
complement: participation.complement || '',
});
}, [participation]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
const response = await fetch(`/api/participations/${participation.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
destinataireEmail: formData.destinataireEmail,
destinataireNom: formData.destinataireNom,
destinataireType: formData.destinataireType,
montant: formData.montant ? parseFloat(formData.montant) : null,
complement: formData.complement || null,
}),
});
if (response.ok) {
onSuccess();
onClose();
} else {
const data = await response.json();
showNotification('error', data.error || 'Erreur lors de la mise à jour');
}
} catch (error) {
showNotification('error', 'Erreur lors de la mise à jour');
} finally {
setLoading(false);
}
};
const handleBackdropClick = (e: React.MouseEvent) => {
if (e.target === e.currentTarget) onClose();
};
const inputBaseClass =
'w-full px-3 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-400 focus:ring-2 focus:ring-lblue focus:border-transparent selection:bg-lblue selection:text-white';
return (
<div
role="dialog"
aria-modal="true"
className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 p-4 animate-fadeIn"
onClick={handleBackdropClick}
>
<div
className="bg-white rounded-lg shadow-xl max-w-lg w-full animate-slideUp border border-gray-200 max-h-[90vh] overflow-y-auto"
onClick={(e) => e.stopPropagation()}
>
<div className="border-b border-gray-200 px-6 py-4">
<h2 className="text-xl font-semibold text-gray-900">Modifier la participation</h2>
<p className="text-sm text-gray-500 mt-1">
{participation.adherent.prenom} {participation.adherent.nom} -{' '}
{new Date(participation.trajet.date).toLocaleDateString('fr-FR')}
</p>
</div>
<form onSubmit={handleSubmit} className="participation-form px-6 py-4 space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Email destinataire</label>
<input
type="email"
value={formData.destinataireEmail}
onChange={(e) => setFormData({ ...formData, destinataireEmail: e.target.value })}
className={inputBaseClass}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Nom destinataire</label>
<input
type="text"
value={formData.destinataireNom}
onChange={(e) => setFormData({ ...formData, destinataireNom: e.target.value })}
className={inputBaseClass}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Type destinataire</label>
<select
value={formData.destinataireType}
onChange={(e) => setFormData({ ...formData, destinataireType: e.target.value })}
className={inputBaseClass}
>
<option value="adherent">Adhérent</option>
<option value="univers_pro">Univers Pro</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Montant ()</label>
<input
type="number"
step="0.01"
min="0"
value={formData.montant}
onChange={(e) => setFormData({ ...formData, montant: e.target.value })}
className={inputBaseClass}
placeholder="6.80"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Informations complémentaires
</label>
<textarea
value={formData.complement}
onChange={(e) => setFormData({ ...formData, complement: e.target.value })}
rows={3}
className={`${inputBaseClass} resize-none`}
placeholder="Notes, commentaires..."
/>
</div>
<div className="flex justify-end gap-3 pt-4 border-t border-gray-200">
<button
type="button"
onClick={onClose}
className="px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-900"
>
Annuler
</button>
<button
type="submit"
disabled={loading}
className="px-6 py-2 text-sm font-medium bg-lblue hover:bg-dblue text-white rounded-lg disabled:opacity-50"
>
{loading ? 'Enregistrement...' : 'Enregistrer'}
</button>
</div>
</form>
</div>
</div>
);
}