espace-paie-odentas/components/staff/ResendInvitationModal.tsx

179 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
);
}