Files
crowdlending-app/frontend/src/pages/ForgotPassword.jsx
T

188 lines
6.7 KiB
React

import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import AuthBgCol from '../components/AuthBgCol.jsx';
export default function ForgotPassword() {
const [email, setEmail] = useState('');
const [status, setStatus] = useState(null); // null | 'sent' | 'error'
const [errMsg, setErrMsg] = useState('');
const [busy, setBusy] = useState(false);
const [appInfo, setAppInfo] = useState({ appName: 'Crowdlending Tracker', iconUrl: null });
useEffect(() => {
fetch('/api/app-info')
.then(r => r.json())
.then(d => setAppInfo(d))
.catch(() => {});
}, []);
const submit = async (e) => {
e.preventDefault();
setErrMsg(''); setBusy(true);
try {
const res = await fetch('/api/auth/forgot-password', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
const data = await res.json();
if (!res.ok) { setErrMsg(data.error || 'Une erreur est survenue.'); setStatus('error'); }
else setStatus('sent');
} catch {
setErrMsg('Impossible de joindre le serveur.'); setStatus('error');
} finally { setBusy(false); }
};
return (
<div style={{ display: 'flex', minHeight: '100dvh' }}>
<AuthBgCol appInfo={appInfo} />
{/* ── Colonne droite — formulaire ──────────────────────── */}
<div style={{
flex: '1 1 50%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: '48px 24px',
background: 'var(--background, #fff)',
minWidth: 0,
}}>
{/* Logo + nom */}
<div style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 10,
marginBottom: 32,
}}>
{appInfo.iconUrl && (
<img src={appInfo.iconUrl} alt={appInfo.appName}
width={52} height={52} style={{ borderRadius: 12 }} />
)}
<span style={{
fontSize: 20, fontWeight: 700,
color: 'var(--text)', letterSpacing: '-0.4px',
}}>
{appInfo.appName}
</span>
</div>
<div style={{ width: '100%', maxWidth: 360 }}>
{status === 'sent' ? (
/* ── Confirmation envoi ── */
<div style={{ textAlign: 'center' }}>
<div style={{
width: 52, height: 52, borderRadius: '50%',
background: 'var(--success-bg, #f0fdf4)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
margin: '0 auto 20px',
}}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M20 6L9 17l-5-5" stroke="var(--success, #16a34a)" strokeWidth="2.2"
strokeLinecap="round" strokeLinejoin="round"/>
</svg>
</div>
<h1 style={{
margin: '0 0 10px', fontSize: 22, fontWeight: 700,
letterSpacing: '-0.4px', color: 'var(--text)',
}}>Email envoyé</h1>
<p style={{ margin: '0 0 28px', color: 'var(--text-muted)', fontSize: 14, lineHeight: 1.6 }}>
Si un compte correspond à <strong>{email}</strong>, vous recevrez
un lien de réinitialisation valable <strong>1 heure</strong>.
</p>
<Link to="/login" style={{
display: 'block', width: '100%', padding: '11px 0',
background: 'var(--primary, #1e40af)', color: '#fff',
borderRadius: 8, fontSize: 15, fontWeight: 600,
textDecoration: 'none', textAlign: 'center',
}}>
Retour à la connexion
</Link>
</div>
) : (
/* ── Formulaire ── */
<>
<div style={{ marginBottom: 28 }}>
<h1 style={{
margin: '0 0 6px', fontSize: 26, fontWeight: 700,
letterSpacing: '-0.5px', color: 'var(--text)',
}}>
Mot de passe oublié ?
</h1>
<p style={{ margin: 0, color: 'var(--text-muted)', fontSize: 14 }}>
Saisissez votre email pour recevoir un lien de réinitialisation.
</p>
</div>
<form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
{status === 'error' && (
<div style={{
padding: '10px 14px', borderRadius: 8, fontSize: 14,
background: 'var(--danger-bg, #fef2f2)',
color: 'var(--danger, #dc2626)',
border: '1px solid var(--danger-light, #fca5a5)',
}}>
{errMsg}
</div>
)}
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
<label style={{ fontSize: 14, fontWeight: 500, color: 'var(--text)' }}>
Adresse email
</label>
<input
className="form-input"
type="email" required
autoComplete="email"
placeholder="vous@exemple.com"
value={email}
onChange={e => setEmail(e.target.value)}
style={{ width: '100%' }}
/>
</div>
<button
type="submit"
disabled={busy}
style={{
marginTop: 4, width: '100%',
padding: '11px 0',
background: busy ? 'var(--text-muted)' : 'var(--primary, #1e40af)',
color: '#fff',
border: 'none', borderRadius: 8,
fontSize: 15, fontWeight: 600,
cursor: busy ? 'not-allowed' : 'pointer',
transition: 'background 0.15s',
}}
>
{busy ? 'Envoi…' : 'Envoyer les instructions'}
</button>
</form>
<p style={{
marginTop: 24, textAlign: 'center',
fontSize: 13, color: 'var(--text-muted)',
}}>
Vous vous souvenez ?{' '}
<Link to="/login" style={{
color: 'var(--text)', fontWeight: 500, textDecoration: 'underline',
}}>
Se connecter
</Link>
</p>
</>
)}
</div>
</div>
</div>
);
}