import { useState, useEffect, useRef } from 'react' import { useLocation } from 'react-router-dom' import UserNav from '../components/UserNav' import { changePasswordApi, meApi, forgotPasswordApi } from '../services/auth' import { useHandleAuthError } from '../hooks/useHandleAuthError' export default function Profile() { const user = JSON.parse(localStorage.getItem('user') || '{}') const initials = `${(user.firstname || '?')[0]}${(user.lastname || '?')[0]}`.toUpperCase() const handleAuthError = useHandleAuthError() const { hash } = useLocation() const deleteSectionRef = useRef(null) // Permet à un lien externe (ex. les CGU) de renvoyer directement sur cette // section via /profile#suppression-compte, plutôt que d'obliger l'utilisateur // à chercher l'information au milieu de la page. useEffect(() => { if (hash === '#suppression-compte') { deleteSectionRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }) } }, [hash]) const [pwForm, setPwForm] = useState({ currentPassword: '', newPassword: '', confirmPassword: '' }) const [showPw, setShowPw] = useState({ current: false, new: false, confirm: false }) const [pwLoading, setPwLoading] = useState(false) const [pwError, setPwError] = useState('') const [pwSuccess, setPwSuccess] = useState(false) // Un compte créé via Google peut ne pas avoir de mot de passe : le // formulaire de modification n'aurait alors aucun sens. L'information vient // de l'API, car le profil stocké en localStorage ne la contient pas. const [hasPassword, setHasPassword] = useState(null) const [linkSending, setLinkSending] = useState(false) const [linkSent, setLinkSent] = useState(false) const [linkError, setLinkError] = useState('') useEffect(() => { meApi() .then((data) => setHasPassword(data.user.hasPassword)) .catch((e) => { if (!handleAuthError(e)) setHasPassword(true) }) }, []) const handleSendSetupLink = async () => { setLinkError('') setLinkSending(true) try { await forgotPasswordApi(user.email) setLinkSent(true) } catch (e) { if (!handleAuthError(e)) setLinkError(e.message) } finally { setLinkSending(false) } } const handlePwChange = (e) => setPwForm({ ...pwForm, [e.target.name]: e.target.value }) const handlePwSubmit = async (e) => { e.preventDefault() setPwError('') setPwSuccess(false) if (pwForm.newPassword !== pwForm.confirmPassword) { setPwError('Les nouveaux mots de passe ne correspondent pas.') return } if (pwForm.newPassword.length < 8) { setPwError('Le nouveau mot de passe doit faire au moins 8 caractères.') return } setPwLoading(true) try { await changePasswordApi({ currentPassword: pwForm.currentPassword, newPassword: pwForm.newPassword }) setPwSuccess(true) setPwForm({ currentPassword: '', newPassword: '', confirmPassword: '' }) } catch (err) { if (!handleAuthError(err)) setPwError(err.message) } finally { setPwLoading(false) } } const EyeIcon = ({ visible }) => ( {visible ? <> : } ) return (
{/* Avatar */}
{initials}
{/* Infos du compte (lecture seule) */}
{user.email || '—'}
{user.lastname || '—'}
{user.firstname || '—'}
{/* Séparateur */}
{/* Section changement de mot de passe */}

{hasPassword === false ? 'Définir un mot de passe' : 'Changer mon mot de passe'}

{hasPassword === false && (

Votre compte a été créé avec Google et n'a pas encore de mot de passe. Définissez-en un pour pouvoir aussi vous connecter avec votre email.

{linkSent ? (

Lien envoyé à {user.email}. Consultez votre boîte mail.

) : ( )} {linkError &&

{linkError}

}
)} {hasPassword !== false && pwSuccess && (
Mot de passe modifié avec succès.
)} {hasPassword !== false && pwError && (
{pwError}
)} {hasPassword !== false && (
{[ { name: 'currentPassword', label: 'Mot de passe actuel', key: 'current' }, { name: 'newPassword', label: 'Nouveau mot de passe', key: 'new' }, { name: 'confirmPassword', label: 'Confirmer le nouveau mot de passe', key: 'confirm' }, ].map(({ name, label, key }) => (
))}
)}
{/* Séparateur */}
{/* Section suppression du compte */}

Supprimer mon compte

Pour des raisons de sécurité, la suppression de compte n'est pas disponible en libre-service. Envoyez-nous un email depuis votre adresse enregistrée ({user.email || '—'}) et notre équipe supprimera votre compte, vos participations et vos gains non retirés.

Demander la suppression par email
) }