179 lines
6.2 KiB
TypeScript
179 lines
6.2 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { X, Mail, Loader2, CheckCircle, AlertCircle } from "lucide-react";
|
||
import { toast } from "sonner";
|
||
|
||
interface ResendInvitationModalProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
salarie: {
|
||
id: string;
|
||
nom?: string | null;
|
||
prenom?: string | null;
|
||
salarie?: string | null;
|
||
adresse_mail?: string | null;
|
||
code_salarie?: string | null;
|
||
};
|
||
onSuccess?: () => void; // Callback pour rafraîchir les données
|
||
}
|
||
|
||
export default function ResendInvitationModal({
|
||
isOpen,
|
||
onClose,
|
||
salarie,
|
||
onSuccess,
|
||
}: ResendInvitationModalProps) {
|
||
const [sending, setSending] = useState(false);
|
||
|
||
if (!isOpen) return null;
|
||
|
||
const salarieName = salarie.salarie || [salarie.prenom, salarie.nom].filter(Boolean).join(" ") || "Salarié";
|
||
const email = salarie.adresse_mail;
|
||
|
||
const handleSend = async () => {
|
||
if (!email) {
|
||
toast.error("Aucune adresse email renseignée pour ce salarié");
|
||
return;
|
||
}
|
||
|
||
setSending(true);
|
||
|
||
try {
|
||
const response = await fetch('/api/auto-declaration/generate-token', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
salarie_id: salarie.id,
|
||
send_email: true,
|
||
}),
|
||
});
|
||
|
||
const data = await response.json();
|
||
|
||
if (!response.ok) {
|
||
throw new Error(data.error || 'Erreur lors de l\'envoi');
|
||
}
|
||
|
||
toast.success('Email de relance envoyé avec succès !');
|
||
onSuccess?.(); // Rafraîchir les données du salarié
|
||
onClose();
|
||
} catch (error) {
|
||
console.error('Erreur envoi relance:', error);
|
||
toast.error(error instanceof Error ? error.message : 'Erreur lors de l\'envoi de la relance');
|
||
} finally {
|
||
setSending(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
|
||
<div className="relative w-full max-w-md bg-white rounded-2xl shadow-2xl">
|
||
{/* Header */}
|
||
<div className="flex items-center justify-between p-5 border-b">
|
||
<div className="flex items-center gap-3">
|
||
<div className="p-2 bg-blue-100 rounded-lg">
|
||
<Mail className="size-5 text-blue-600" />
|
||
</div>
|
||
<h2 className="text-lg font-semibold text-slate-800">
|
||
Relancer le salarié
|
||
</h2>
|
||
</div>
|
||
<button
|
||
onClick={onClose}
|
||
disabled={sending}
|
||
className="p-2 hover:bg-slate-100 rounded-lg transition-colors disabled:opacity-50"
|
||
>
|
||
<X className="size-5 text-slate-500" />
|
||
</button>
|
||
</div>
|
||
|
||
{/* Body */}
|
||
<div className="p-5 space-y-4">
|
||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||
<div className="flex items-start gap-3">
|
||
<CheckCircle className="size-5 text-blue-600 flex-shrink-0 mt-0.5" />
|
||
<div className="flex-1">
|
||
<p className="text-sm font-medium text-blue-900 mb-1">
|
||
Email d'invitation à l'auto-déclaration
|
||
</p>
|
||
<p className="text-xs text-blue-700">
|
||
Le salarié recevra un email avec un lien sécurisé pour compléter ses informations et télécharger ses justificatifs.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Infos du salarié */}
|
||
<div className="space-y-2">
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-slate-600">Salarié :</span>
|
||
<span className="font-medium text-slate-800">{salarieName}</span>
|
||
</div>
|
||
{salarie.code_salarie && (
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-slate-600">Matricule :</span>
|
||
<span className="font-medium text-slate-800">{salarie.code_salarie}</span>
|
||
</div>
|
||
)}
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-slate-600">Email :</span>
|
||
{email ? (
|
||
<span className="font-medium text-slate-800">{email}</span>
|
||
) : (
|
||
<span className="flex items-center gap-1 text-red-600">
|
||
<AlertCircle className="size-3" />
|
||
Non renseigné
|
||
</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{!email && (
|
||
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
|
||
<p className="text-xs text-red-700">
|
||
⚠️ Impossible d'envoyer l'email : aucune adresse email renseignée pour ce salarié.
|
||
</p>
|
||
</div>
|
||
)}
|
||
|
||
<div className="bg-slate-50 border border-slate-200 rounded-lg p-3">
|
||
<p className="text-xs text-slate-600">
|
||
💡 <strong>Contenu de l'email :</strong> Lien d'accès personnalisé valide 7 jours, instructions pour compléter le profil et uploader les documents (CNI, attestation Sécu, RIB, etc.).
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Footer */}
|
||
<div className="flex items-center justify-end gap-3 p-5 border-t bg-slate-50 rounded-b-2xl">
|
||
<button
|
||
onClick={onClose}
|
||
disabled={sending}
|
||
className="px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-200 rounded-lg transition-colors disabled:opacity-50"
|
||
>
|
||
Annuler
|
||
</button>
|
||
<button
|
||
onClick={handleSend}
|
||
disabled={!email || sending}
|
||
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
|
||
>
|
||
{sending ? (
|
||
<>
|
||
<Loader2 className="size-4 animate-spin" />
|
||
Envoi en cours...
|
||
</>
|
||
) : (
|
||
<>
|
||
<Mail className="size-4" />
|
||
Envoyer la relance
|
||
</>
|
||
)}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|