796 lines
33 KiB
TypeScript
796 lines
33 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import Navbar from "../../components/Navbar";
|
|
import {
|
|
isUserAuthenticated,
|
|
extractUsernameFromToken,
|
|
getMyProfile,
|
|
updateMyProfile,
|
|
getTelegramStatus,
|
|
generateTelegramLinkToken,
|
|
unlinkTelegram,
|
|
get2FAStatus,
|
|
toggle2FA,
|
|
getPublicSettings,
|
|
} from "../../api/api";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import {
|
|
faUser,
|
|
faMapMarkerAlt,
|
|
faPhone,
|
|
faCommentDots,
|
|
faSave,
|
|
faCheckCircle,
|
|
faExclamationTriangle,
|
|
faPaperPlane,
|
|
faUnlink,
|
|
faTimes,
|
|
faLock,
|
|
faShieldAlt,
|
|
} from "@fortawesome/free-solid-svg-icons";
|
|
import "./ProfilePage.css";
|
|
|
|
const STORAGE_ADDRESS = "profile_default_address";
|
|
const STORAGE_PHONE = "profile_default_phone";
|
|
const STORAGE_SIGNAL = "profile_signal_pseudo";
|
|
|
|
export default function ProfilePage() {
|
|
const navigate = useNavigate();
|
|
|
|
// Données compte (backend)
|
|
const [nom, setNom] = useState("");
|
|
const [prenom, setPrenom] = useState("");
|
|
const [telephone, setTelephone] = useState("");
|
|
const [loadingProfile, setLoadingProfile] = useState(true);
|
|
|
|
// Données locales (localStorage)
|
|
const [defaultAddress, setDefaultAddress] = useState(
|
|
() => localStorage.getItem(STORAGE_ADDRESS) ?? "",
|
|
);
|
|
const [defaultPhone, setDefaultPhone] = useState(
|
|
() => localStorage.getItem(STORAGE_PHONE) ?? "",
|
|
);
|
|
const [signalPseudo, setSignalPseudo] = useState(
|
|
() => localStorage.getItem(STORAGE_SIGNAL) ?? "",
|
|
);
|
|
|
|
const [savingContact, setSavingContact] = useState(false);
|
|
|
|
// Modals succès / erreur (pattern identique à l'app mobile)
|
|
const [showSuccessModal, setShowSuccessModal] = useState(false);
|
|
const [successTitle, setSuccessTitle] = useState("");
|
|
const [successMsg, setSuccessMsg] = useState("");
|
|
const [showErrorModal, setShowErrorModal] = useState(false);
|
|
const [errorMsg, setErrorMsg] = useState("");
|
|
|
|
// Telegram
|
|
const [tgLinked, setTgLinked] = useState(false);
|
|
const [tgEnabled, setTgEnabled] = useState(false);
|
|
const [tgLoading, setTgLoading] = useState(false);
|
|
|
|
// 2FA
|
|
const [twoFAEnabled, setTwoFAEnabled] = useState(false);
|
|
const [twoFAAdminEnabled, setTwoFAAdminEnabled] = useState(false);
|
|
const [twoFALoading, setTwoFALoading] = useState(false);
|
|
|
|
// SAV Telegram
|
|
const [savTelegramUrl, setSavTelegramUrl] = useState("");
|
|
|
|
// Modals confirmation
|
|
const [showSaveModal, setShowSaveModal] = useState(false);
|
|
const [showConfirmAddressModal, setShowConfirmAddressModal] =
|
|
useState(false);
|
|
const [showConfirmContactModal, setShowConfirmContactModal] =
|
|
useState(false);
|
|
const [showUnlinkModal, setShowUnlinkModal] = useState(false);
|
|
const [showUnlinkSuccessModal, setShowUnlinkSuccessModal] = useState(false);
|
|
|
|
const username = extractUsernameFromToken() ?? "";
|
|
|
|
useEffect(() => {
|
|
if (!isUserAuthenticated()) {
|
|
navigate("/login/client", { replace: true });
|
|
return;
|
|
}
|
|
// Statut Telegram
|
|
getTelegramStatus().then((s) => {
|
|
setTgLinked(s.linked);
|
|
setTgEnabled(s.enabled);
|
|
});
|
|
|
|
// Statut 2FA
|
|
Promise.all([get2FAStatus(), getPublicSettings()]).then(
|
|
([status, pub]) => {
|
|
setTwoFAEnabled(status.two_fa_enabled);
|
|
setTwoFAAdminEnabled(pub.two_fa_enabled);
|
|
if (pub.contact_telegram) {
|
|
const ct = pub.contact_telegram;
|
|
setSavTelegramUrl(
|
|
ct.startsWith("http")
|
|
? ct
|
|
: `https://t.me/${ct.replace(/^@/, "")}`,
|
|
);
|
|
}
|
|
},
|
|
);
|
|
|
|
// Charger depuis backend
|
|
getMyProfile().then((res) => {
|
|
if (res.success && res.client) {
|
|
setNom(res.client.nom ?? "");
|
|
setPrenom(res.client.prenom ?? "");
|
|
setTelephone(res.client.telephone ?? "");
|
|
// Initialiser le téléphone par défaut si pas encore défini
|
|
if (
|
|
!localStorage.getItem(STORAGE_PHONE) &&
|
|
res.client.telephone
|
|
) {
|
|
setDefaultPhone(res.client.telephone);
|
|
}
|
|
}
|
|
setLoadingProfile(false);
|
|
});
|
|
}, [navigate]);
|
|
|
|
const showSuccess = (title: string, msg: string) => {
|
|
setSuccessTitle(title);
|
|
setSuccessMsg(msg);
|
|
setShowSuccessModal(true);
|
|
};
|
|
const showError = (msg: string) => {
|
|
setErrorMsg(msg);
|
|
setShowErrorModal(true);
|
|
};
|
|
|
|
const saveAddress = () => {
|
|
localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim());
|
|
setShowConfirmAddressModal(false);
|
|
showSuccess(
|
|
"Adresse enregistrée",
|
|
"Votre adresse par défaut a été sauvegardée et sera pré-remplie à votre prochaine commande.",
|
|
);
|
|
};
|
|
|
|
const saveLocal = () => {
|
|
localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim());
|
|
localStorage.setItem(STORAGE_PHONE, defaultPhone.trim());
|
|
localStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim());
|
|
setShowSaveModal(false);
|
|
showSuccess(
|
|
"Infos enregistrées",
|
|
"Adresse, téléphone et pseudo Signal sauvegardés. Ils seront pré-remplis à votre prochaine commande.",
|
|
);
|
|
};
|
|
|
|
const handleLinkTelegram = async () => {
|
|
setTgLoading(true);
|
|
const res = await generateTelegramLinkToken();
|
|
setTgLoading(false);
|
|
if (res.error || !res.link_url) {
|
|
showError(res.error || "Service Telegram non disponible");
|
|
return;
|
|
}
|
|
window.open(res.link_url, "_blank");
|
|
};
|
|
|
|
const handleUnlinkTelegram = () => {
|
|
setShowUnlinkModal(true);
|
|
};
|
|
|
|
const confirmUnlinkTelegram = async () => {
|
|
setShowUnlinkModal(false);
|
|
await unlinkTelegram();
|
|
setTgLinked(false);
|
|
setTwoFAEnabled(false);
|
|
setShowUnlinkSuccessModal(true);
|
|
};
|
|
|
|
const handleToggle2FA = async () => {
|
|
const newVal = !twoFAEnabled;
|
|
setTwoFALoading(true);
|
|
const res = await toggle2FA(newVal);
|
|
setTwoFALoading(false);
|
|
if (res.success) {
|
|
setTwoFAEnabled(newVal);
|
|
showSuccess(
|
|
newVal ? "2FA activée" : "2FA désactivée",
|
|
newVal
|
|
? "Un code vous sera envoyé sur Telegram à chaque connexion."
|
|
: "La double authentification a été désactivée.",
|
|
);
|
|
} else {
|
|
showError(res.error || "Erreur lors de la modification");
|
|
}
|
|
};
|
|
|
|
const saveContact = async () => {
|
|
setShowConfirmContactModal(false);
|
|
setSavingContact(true);
|
|
const res = await updateMyProfile({
|
|
nom: nom.trim(),
|
|
prenom: prenom.trim(),
|
|
telephone: telephone.trim(),
|
|
});
|
|
setSavingContact(false);
|
|
if (res.success) {
|
|
showSuccess(
|
|
"Profil mis à jour",
|
|
"Vos informations de compte ont été enregistrées avec succès.",
|
|
);
|
|
} else {
|
|
showError(
|
|
res.message ?? "Erreur lors de la mise à jour du profil.",
|
|
);
|
|
}
|
|
};
|
|
|
|
if (loadingProfile) {
|
|
return (
|
|
<>
|
|
<Navbar />
|
|
<div className="profile-container">
|
|
<div className="profile-loading">
|
|
<div className="spinner" />
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Navbar />
|
|
<div className="profile-container">
|
|
<div className="profile-header">
|
|
<div className="profile-avatar">
|
|
<FontAwesomeIcon icon={faUser} />
|
|
</div>
|
|
<div>
|
|
<h1 className="profile-title">Mon Profil</h1>
|
|
<p className="profile-username">{username}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Section compte */}
|
|
<div className="profile-card">
|
|
<h2 className="profile-card-title">
|
|
<FontAwesomeIcon
|
|
icon={faUser}
|
|
className="profile-card-icon"
|
|
/>
|
|
Mon compte
|
|
</h2>
|
|
<div className="profile-fields">
|
|
<div className="profile-row">
|
|
<div className="profile-group">
|
|
<label>Prénom</label>
|
|
<input
|
|
type="text"
|
|
value={prenom}
|
|
onChange={(e) => setPrenom(e.target.value)}
|
|
placeholder="Votre prénom"
|
|
/>
|
|
</div>
|
|
<div className="profile-group">
|
|
<label>Nom</label>
|
|
<input
|
|
type="text"
|
|
value={nom}
|
|
onChange={(e) => setNom(e.target.value)}
|
|
placeholder="Votre nom"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="profile-group">
|
|
<label>Téléphone (compte)</label>
|
|
<input
|
|
type="tel"
|
|
value={telephone}
|
|
onChange={(e) => setTelephone(e.target.value)}
|
|
placeholder="+33 6 12 34 56 78"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<button
|
|
className="profile-btn"
|
|
onClick={() => setShowConfirmContactModal(true)}
|
|
disabled={savingContact}
|
|
>
|
|
<FontAwesomeIcon icon={faSave} />
|
|
{savingContact
|
|
? " Enregistrement..."
|
|
: " Enregistrer le compte"}
|
|
</button>
|
|
<button
|
|
className="profile-btn profile-btn--secondary"
|
|
onClick={() => navigate("/user/change-password")}
|
|
style={{ marginTop: "0.6rem" }}
|
|
>
|
|
<FontAwesomeIcon icon={faLock} /> Changer le mot de
|
|
passe
|
|
</button>
|
|
</div>
|
|
|
|
{/* Section adresse par défaut */}
|
|
<div className="profile-card">
|
|
<h2 className="profile-card-title">
|
|
<FontAwesomeIcon
|
|
icon={faMapMarkerAlt}
|
|
className="profile-card-icon profile-card-icon--address"
|
|
/>
|
|
Adresse par défaut
|
|
</h2>
|
|
<p className="profile-hint">
|
|
Sera pré-remplie dans le formulaire de commande. Vous
|
|
pourrez la modifier si vous n'êtes pas à cette adresse.
|
|
</p>
|
|
<div className="profile-group">
|
|
<label>Adresse</label>
|
|
<input
|
|
type="text"
|
|
value={defaultAddress}
|
|
onChange={(e) => setDefaultAddress(e.target.value)}
|
|
placeholder="Numéro, rue, ville, code postal"
|
|
/>
|
|
</div>
|
|
<button
|
|
className="profile-btn profile-btn--secondary"
|
|
onClick={() => setShowConfirmAddressModal(true)}
|
|
style={{ marginTop: "0.8rem" }}
|
|
>
|
|
<FontAwesomeIcon icon={faSave} /> Enregistrer l'adresse
|
|
</button>
|
|
</div>
|
|
|
|
{/* Section contact commande */}
|
|
<div className="profile-card">
|
|
<h2 className="profile-card-title">
|
|
<FontAwesomeIcon
|
|
icon={faPhone}
|
|
className="profile-card-icon profile-card-icon--phone"
|
|
/>
|
|
Contact livraison
|
|
</h2>
|
|
<p className="profile-hint">
|
|
Numéro utilisé par le livreur lors de la livraison. Peut
|
|
être différent du numéro de votre compte.
|
|
</p>
|
|
<div className="profile-group">
|
|
<label>Téléphone par défaut</label>
|
|
<input
|
|
type="tel"
|
|
value={defaultPhone}
|
|
onChange={(e) => setDefaultPhone(e.target.value)}
|
|
placeholder="+33 6 12 34 56 78"
|
|
/>
|
|
</div>
|
|
<div
|
|
className="profile-group"
|
|
style={{ marginTop: "1rem" }}
|
|
>
|
|
<label>
|
|
<FontAwesomeIcon
|
|
icon={faCommentDots}
|
|
style={{ marginRight: "0.4rem" }}
|
|
/>
|
|
Pseudo Signal (optionnel)
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={signalPseudo}
|
|
onChange={(e) => setSignalPseudo(e.target.value)}
|
|
placeholder="@votre.pseudo.signal"
|
|
/>
|
|
</div>
|
|
<button
|
|
className="profile-btn profile-btn--secondary"
|
|
onClick={() => setShowSaveModal(true)}
|
|
>
|
|
<FontAwesomeIcon icon={faSave} /> Enregistrer les infos
|
|
par défaut
|
|
</button>
|
|
</div>
|
|
{/* Section Telegram */}
|
|
{tgEnabled && (
|
|
<div className="profile-card">
|
|
<h2 className="profile-card-title">
|
|
<FontAwesomeIcon
|
|
icon={faPaperPlane}
|
|
className="profile-card-icon profile-card-icon--telegram"
|
|
/>
|
|
Notifications Telegram
|
|
</h2>
|
|
<p className="profile-hint">
|
|
Recevez vos notifications sur Telegram, même quand
|
|
le site est fermé.
|
|
</p>
|
|
{tgLinked ? (
|
|
<div className="profile-telegram-linked">
|
|
<span className="profile-telegram-status">
|
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
|
Compte Telegram lié
|
|
</span>
|
|
<button
|
|
className="profile-btn profile-btn--danger"
|
|
onClick={handleUnlinkTelegram}
|
|
>
|
|
<FontAwesomeIcon icon={faUnlink} /> Délier
|
|
Telegram
|
|
</button>
|
|
</div>
|
|
) : (
|
|
<button
|
|
className="profile-btn profile-btn--telegram"
|
|
onClick={handleLinkTelegram}
|
|
disabled={tgLoading}
|
|
>
|
|
<FontAwesomeIcon icon={faPaperPlane} />
|
|
{tgLoading
|
|
? " Génération du lien..."
|
|
: " Lier mon compte Telegram"}
|
|
</button>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{/* Section SAV Telegram */}
|
|
{savTelegramUrl && (
|
|
<div className="profile-card">
|
|
<h2 className="profile-card-title">
|
|
<FontAwesomeIcon
|
|
icon={faPaperPlane}
|
|
className="profile-card-icon profile-card-icon--telegram"
|
|
/>
|
|
Contacter le SAV
|
|
</h2>
|
|
<p className="profile-hint">
|
|
Un problème avec votre commande ? Contactez notre
|
|
service après-vente directement sur Telegram.
|
|
</p>
|
|
<a
|
|
href={savTelegramUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="profile-btn profile-btn--telegram"
|
|
style={{ textDecoration: "none" }}
|
|
>
|
|
<FontAwesomeIcon icon={faPaperPlane} /> Contacter
|
|
le SAV sur Telegram
|
|
</a>
|
|
</div>
|
|
)}
|
|
|
|
{/* Section 2FA — visible uniquement si l'admin l'a activé ET Telegram est lié */}
|
|
{twoFAAdminEnabled && tgLinked && (
|
|
<div className="profile-card">
|
|
<h2 className="profile-card-title">
|
|
<FontAwesomeIcon
|
|
icon={faShieldAlt}
|
|
className="profile-card-icon"
|
|
style={{ color: "#6366f1" }}
|
|
/>
|
|
Double authentification (2FA)
|
|
</h2>
|
|
<p className="profile-hint">
|
|
À chaque connexion, un code à 6 chiffres vous sera
|
|
envoyé sur Telegram avant d'accéder à votre compte.
|
|
</p>
|
|
<div className="profile-2fa-row">
|
|
<div className="profile-2fa-label">
|
|
<span>
|
|
{twoFAEnabled ? "Activée" : "Désactivée"}
|
|
</span>
|
|
{twoFAEnabled && (
|
|
<span className="profile-2fa-badge">
|
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
|
Protection active
|
|
</span>
|
|
)}
|
|
</div>
|
|
{twoFALoading ? (
|
|
<div className="profile-2fa-spinner" />
|
|
) : (
|
|
<button
|
|
role="switch"
|
|
aria-checked={twoFAEnabled}
|
|
className={`profile-toggle ${twoFAEnabled ? "profile-toggle--on" : ""}`}
|
|
onClick={handleToggle2FA}
|
|
aria-label="Activer ou désactiver la double authentification"
|
|
>
|
|
<span className="profile-toggle-thumb" />
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{showSaveModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowSaveModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowSaveModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon">
|
|
<FontAwesomeIcon icon={faSave} />
|
|
</div>
|
|
<h3 className="profile-modal-title">
|
|
Enregistrer les infos par défaut ?
|
|
</h3>
|
|
<p className="profile-modal-body">
|
|
Adresse, téléphone de livraison et pseudo Signal
|
|
seront sauvegardés localement et pré-remplis lors de
|
|
vos prochaines commandes.
|
|
</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--cancel"
|
|
onClick={() => setShowSaveModal(false)}
|
|
>
|
|
Annuler
|
|
</button>
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--confirm"
|
|
onClick={saveLocal}
|
|
>
|
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
|
Confirmer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{showConfirmAddressModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowConfirmAddressModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowConfirmAddressModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon">
|
|
<FontAwesomeIcon icon={faMapMarkerAlt} />
|
|
</div>
|
|
<h3 className="profile-modal-title">
|
|
Enregistrer l'adresse ?
|
|
</h3>
|
|
<p className="profile-modal-body">
|
|
Cette adresse sera sauvegardée localement et
|
|
pré-remplie lors de vos prochaines commandes.
|
|
</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--cancel"
|
|
onClick={() =>
|
|
setShowConfirmAddressModal(false)
|
|
}
|
|
>
|
|
Annuler
|
|
</button>
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--confirm"
|
|
onClick={saveAddress}
|
|
>
|
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
|
Confirmer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{showConfirmContactModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowConfirmContactModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowConfirmContactModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon">
|
|
<FontAwesomeIcon icon={faUser} />
|
|
</div>
|
|
<h3 className="profile-modal-title">
|
|
Enregistrer le compte ?
|
|
</h3>
|
|
<p className="profile-modal-body">
|
|
Vos informations (prénom, nom, téléphone) seront
|
|
mises à jour sur votre compte.
|
|
</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--cancel"
|
|
onClick={() =>
|
|
setShowConfirmContactModal(false)
|
|
}
|
|
>
|
|
Annuler
|
|
</button>
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--confirm"
|
|
onClick={saveContact}
|
|
disabled={savingContact}
|
|
>
|
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
|
{savingContact
|
|
? "Enregistrement..."
|
|
: "Confirmer"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{showUnlinkModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowUnlinkModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowUnlinkModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon profile-modal-icon--danger">
|
|
<FontAwesomeIcon icon={faUnlink} />
|
|
</div>
|
|
<h3 className="profile-modal-title">
|
|
Délier Telegram ?
|
|
</h3>
|
|
<p className="profile-modal-body">
|
|
Vous ne recevrez plus de notifications Telegram. La
|
|
double authentification sera également désactivée.
|
|
</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--cancel"
|
|
onClick={() => setShowUnlinkModal(false)}
|
|
>
|
|
Annuler
|
|
</button>
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--danger"
|
|
onClick={confirmUnlinkTelegram}
|
|
>
|
|
<FontAwesomeIcon icon={faUnlink} /> Délier
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Modal succès */}
|
|
{showSuccessModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowSuccessModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowSuccessModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon profile-modal-icon--success">
|
|
<FontAwesomeIcon icon={faCheckCircle} />
|
|
</div>
|
|
<h3 className="profile-modal-title">{successTitle}</h3>
|
|
<p className="profile-modal-body">{successMsg}</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--confirm profile-modal-btn--success"
|
|
onClick={() => setShowSuccessModal(false)}
|
|
>
|
|
Fermer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Modal erreur */}
|
|
{showErrorModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowErrorModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowErrorModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon profile-modal-icon--danger">
|
|
<FontAwesomeIcon icon={faExclamationTriangle} />
|
|
</div>
|
|
<h3 className="profile-modal-title">
|
|
Une erreur est survenue
|
|
</h3>
|
|
<p className="profile-modal-body">{errorMsg}</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--danger"
|
|
onClick={() => setShowErrorModal(false)}
|
|
>
|
|
Fermer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{showUnlinkSuccessModal && (
|
|
<div
|
|
className="profile-modal-overlay"
|
|
onClick={() => setShowUnlinkSuccessModal(false)}
|
|
>
|
|
<div
|
|
className="profile-modal"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
className="profile-modal-close"
|
|
onClick={() => setShowUnlinkSuccessModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faTimes} />
|
|
</button>
|
|
<div className="profile-modal-icon profile-modal-icon--success">
|
|
<FontAwesomeIcon icon={faCheckCircle} />
|
|
</div>
|
|
<h3 className="profile-modal-title">Compte délié</h3>
|
|
<p className="profile-modal-body">
|
|
Votre compte Telegram a été délié avec succès. Vous
|
|
ne recevrez plus de notifications via Telegram.
|
|
</p>
|
|
<div className="profile-modal-actions">
|
|
<button
|
|
className="profile-modal-btn profile-modal-btn--confirm"
|
|
onClick={() => setShowUnlinkSuccessModal(false)}
|
|
>
|
|
<FontAwesomeIcon icon={faCheckCircle} /> Fermer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|