Feature: Suppression de son compte
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '../context/AuthContext.jsx';
|
||||
import { api } from '../api.js';
|
||||
import AuthBgCol from '../components/AuthBgCol.jsx';
|
||||
@@ -28,6 +28,8 @@ function AppHeader({ appInfo }) {
|
||||
export default function Login() {
|
||||
const { login, completeLogin } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const accountDeleted = searchParams.get('deleted') === '1';
|
||||
|
||||
const [appInfo, setAppInfo] = useState({ appName: 'Crowdlending Tracker', iconUrl: null, allowRegistration: true });
|
||||
|
||||
@@ -193,6 +195,12 @@ export default function Login() {
|
||||
<form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
<ErrBox msg={err} />
|
||||
|
||||
{accountDeleted && !err && (
|
||||
<div style={{ padding: '10px 14px', borderRadius: 8, fontSize: 14, background: 'var(--success-bg, #f0fdf4)', color: 'var(--success, #16a34a)', border: '1px solid #bbf7d0' }}>
|
||||
Votre compte a été supprimé avec succès.
|
||||
</div>
|
||||
)}
|
||||
|
||||
{unverified && (
|
||||
<div style={{ padding: '12px 14px', borderRadius: 8, fontSize: 13, background: 'var(--warning-bg, #fffbeb)', color: 'var(--warning-text, #92400e)', border: '1px solid var(--warning-border, #fcd34d)', lineHeight: 1.5 }}>
|
||||
<strong>Email non vérifié.</strong> Vérifiez votre boîte mail et cliquez sur le lien reçu.
|
||||
|
||||
@@ -713,6 +713,75 @@ function TrustedDevicesSection() {
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Suppression définitive du compte ────────────────────────── */
|
||||
function DeleteAccountSection() {
|
||||
const { deleteAccount } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [confirming, setConfirming] = useState(false);
|
||||
const [password, setPassword] = useState('');
|
||||
const [err, setErr] = useState(null);
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
const submit = async (e) => {
|
||||
e.preventDefault();
|
||||
setErr(null); setBusy(true);
|
||||
try {
|
||||
await deleteAccount(password);
|
||||
navigate('/login?deleted=1', { replace: true });
|
||||
} catch (e) {
|
||||
setErr(e.message || 'Une erreur est survenue.');
|
||||
} finally { setBusy(false); }
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="card" style={{ marginTop: 20, border: '1px solid var(--danger,#dc2626)' }}>
|
||||
<h3 style={{ margin: '0 0 4px', color: 'var(--danger,#dc2626)' }}>Supprimer mon compte</h3>
|
||||
<p className="text-muted" style={{ margin: '0 0 16px', fontSize: 'var(--fs-sm)' }}>
|
||||
Cette action est <strong>définitive et irréversible</strong>. Toutes vos données seront immédiatement
|
||||
supprimées : plateformes, investissements, remboursements, dépôts/retraits, comptes courants,
|
||||
préférences et historique. Il ne sera pas possible de les récupérer.
|
||||
</p>
|
||||
|
||||
{err && <div className="error" style={{ marginBottom: 12 }}>{err}</div>}
|
||||
|
||||
{!confirming && (
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<button type="button" className="danger"
|
||||
onClick={() => setConfirming(true)}>
|
||||
Supprimer mon compte
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{confirming && (
|
||||
<form onSubmit={submit} style={{
|
||||
marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)',
|
||||
display: 'flex', flexDirection: 'column', gap: 12, maxWidth: 400,
|
||||
}}>
|
||||
<p style={{ margin: 0, fontSize: 13, color: 'var(--text-muted)' }}>
|
||||
Confirmez votre mot de passe pour supprimer définitivement votre compte.
|
||||
</p>
|
||||
<div>
|
||||
<label>Mot de passe actuel</label>
|
||||
<PasswordInput required autoComplete="current-password" placeholder="••••••••"
|
||||
value={password} onChange={e => setPassword(e.target.value)} />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 12 }}>
|
||||
<button type="submit" className="danger"
|
||||
disabled={busy || !password}>
|
||||
{busy ? 'Suppression…' : 'Confirmer la suppression définitive'}
|
||||
</button>
|
||||
<button type="button" onClick={() => { setConfirming(false); setPassword(''); setErr(null); }}
|
||||
style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: 13, cursor: 'pointer', textDecoration: 'underline', padding: 0 }}>
|
||||
Annuler
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Page principale ─────────────────────────────────────────── */
|
||||
export default function MonCompte() {
|
||||
const { search } = useLocation();
|
||||
@@ -747,7 +816,7 @@ export default function MonCompte() {
|
||||
{/* ── Contenu ─────────────────────────────────────── */}
|
||||
<div className="account-content account-content-center">
|
||||
<div className="account-content-narrow">
|
||||
{section === 'profil' && <AccountForm />}
|
||||
{section === 'profil' && <><AccountForm /><DeleteAccountSection /></>}
|
||||
{section === 'securite' && <><SecurityForm /><TwoFASection user={user} /><TrustedDevicesSection /></>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user