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) ?? ''); // Feedback const [savingContact, setSavingContact] = useState(false); const [successMsg, setSuccessMsg] = useState(''); 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); // Modal confirmation infos par défaut const [showSaveModal, setShowSaveModal] = 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); }); // 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 = (msg: string) => { setSuccessMsg(msg); setErrorMsg(''); setTimeout(() => setSuccessMsg(''), 3000); }; const showError = (msg: string) => { setErrorMsg(msg); setSuccessMsg(''); setTimeout(() => setErrorMsg(''), 4000); }; const saveAddress = () => { localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim()); showSuccess('Adresse par défaut enregistrée'); }; const saveLocal = () => { localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim()); localStorage.setItem(STORAGE_PHONE, defaultPhone.trim()); localStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim()); setShowSaveModal(false); showSuccess('Informations par défaut enregistrées'); }; 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 ? 'Double authentification activée' : 'Double authentification désactivée'); } else { showError(res.error || 'Erreur lors de la modification'); } }; const saveContact = async () => { setSavingContact(true); const res = await updateMyProfile({ nom: nom.trim(), prenom: prenom.trim(), telephone: telephone.trim() }); setSavingContact(false); if (res.success) { showSuccess('Profil mis à jour'); } else { showError(res.message ?? 'Erreur lors de la mise à jour'); } }; if (loadingProfile) { return ( <>
); } return ( <>

Mon Profil

@{username}

{successMsg && (
{successMsg}
)} {errorMsg && (
{errorMsg}
)} {/* Section compte */}

Mon compte

setPrenom(e.target.value)} placeholder="Votre prénom" />
setNom(e.target.value)} placeholder="Votre nom" />
setTelephone(e.target.value)} placeholder="+33 6 12 34 56 78" />
{/* Section adresse par défaut */}

Adresse par défaut

Sera pré-remplie dans le formulaire de commande. Vous pourrez la modifier si vous n'êtes pas à cette adresse.

setDefaultAddress(e.target.value)} placeholder="Numéro, rue, ville, code postal" />
{/* Section contact commande */}

Contact livraison

Numéro utilisé par le livreur lors de la livraison. Peut être différent du numéro de votre compte.

setDefaultPhone(e.target.value)} placeholder="+33 6 12 34 56 78" />
setSignalPseudo(e.target.value)} placeholder="@votre.pseudo.signal" />
{/* Section Telegram */} {tgEnabled && (

Notifications Telegram

Recevez vos notifications sur Telegram, même quand le site est fermé.

{tgLinked ? (
Compte Telegram lié
) : ( )}
)} {/* Section 2FA — visible uniquement si l'admin l'a activé ET Telegram est lié */} {twoFAAdminEnabled && tgLinked && (

Double authentification (2FA)

À chaque connexion, un code à 6 chiffres vous sera envoyé sur Telegram avant d'accéder à votre compte.

{twoFAEnabled ? 'Activée' : 'Désactivée'} {twoFAEnabled && ( Protection active )}
{twoFALoading ? (
) : ( )}
)}
{showSaveModal && (
setShowSaveModal(false)}>
e.stopPropagation()}>

Enregistrer les infos par défaut ?

Adresse, téléphone de livraison et pseudo Signal seront sauvegardés localement et pré-remplis lors de vos prochaines commandes.

)} {showUnlinkModal && (
setShowUnlinkModal(false)}>
e.stopPropagation()}>

Délier Telegram ?

Vous ne recevrez plus de notifications Telegram. La double authentification sera également désactivée.

)} {showUnlinkSuccessModal && (
setShowUnlinkSuccessModal(false)}>
e.stopPropagation()}>

Compte délié

Votre compte Telegram a été délié avec succès. Vous ne recevrez plus de notifications via Telegram.

)} ); }