Fix multi-détenteur

This commit is contained in:
2026-07-14 15:35:35 +02:00
parent 069e316362
commit 3a9de15526
@@ -44,6 +44,7 @@ export default function DataCleanupSection() {
const [purgeScope, setPurgeScope] = useState('all');
const [showPurgeModal, setShowPurgeModal] = useState(false);
const [purgeConfirmText, setPurgeConfirmText] = useState('');
const [purgePin, setPurgePin] = useState('');
const [loadingPurge, setLoadingPurge] = useState(false);
useEffect(() => {
@@ -51,22 +52,29 @@ export default function DataCleanupSection() {
}, []);
const purgePlat = plats.find(p => String(p.id) === String(purgePlatId)) || null;
// Plusieurs membres de la famille/entreprise peuvent avoir une plateforme du même nom
// (ex. deux comptes "Enky" distincts) — on ajoute le détenteur au libellé pour lever
// l'ambiguïté, uniquement quand plus d'un détenteur est présent dans la liste.
const multiDetenteurPlats = new Set(plats.map(p => p.investisseur_id)).size > 1;
const openPurgeModal = () => {
if (!purgePlat) return;
setPurgeConfirmText('');
setPurgePin(String(Math.floor(100000 + Math.random() * 900000)));
setShowPurgeModal(true);
};
const handlePurge = async () => {
if (!purgePlat || purgeConfirmText.trim() !== purgePlat.nom) return;
if (!purgePlat || purgeConfirmText.trim() !== purgePin) return;
setLoadingPurge(true);
setErrorMsg(null);
setSuccessMsg(null);
try {
const r = await api.post(`/plateformes/${purgePlat.id}/purge-donnees`, {
scope: purgeScope,
confirmNom: purgeConfirmText.trim(),
// Le PIN est une confirmation côté interface uniquement ; l'API continue d'exiger
// le nom exact de la plateforme, déjà connu ici puisque sélectionné dans le formulaire.
confirmNom: purgePlat.nom,
});
setSuccessMsg(`"${r.plateforme}" — ${purgeSummary(r.counts, purgeScope)}`);
setShowPurgeModal(false);
@@ -300,7 +308,11 @@ export default function DataCleanupSection() {
<label style={{ fontSize: 12 }}>Plateforme</label>
<select value={purgePlatId} onChange={e => setPurgePlatId(e.target.value)}>
<option value="">Sélectionnez une plateforme…</option>
{plats.map(p => <option key={p.id} value={p.id}>{p.nom}</option>)}
{plats.map(p => (
<option key={p.id} value={p.id}>
{p.nom}{multiDetenteurPlats && p.investisseur_nom ? ` — ${p.investisseur_nom}` : ''}
</option>
))}
</select>
</div>
<div style={{ flex: '1 1 280px', minWidth: 240 }}>
@@ -474,7 +486,8 @@ export default function DataCleanupSection() {
<h3 style={{ margin: 0, color: 'var(--danger, #ef4444)' }}> Suppression de données action irréversible</h3>
</div>
<p style={{ margin: '0 0 12px', lineHeight: 1.6 }}>
Vous vous apprêtez à supprimer, pour la plateforme <strong>{purgePlat.nom}</strong> :
Vous vous apprêtez à supprimer, pour la plateforme <strong>{purgePlat.nom}</strong>
{multiDetenteurPlats && purgePlat.investisseur_nom ? <> (<strong>{purgePlat.investisseur_nom}</strong>)</> : null} :
</p>
<p style={{ margin: '0 0 12px', lineHeight: 1.6, fontFamily: 'monospace', fontSize: 13,
background: 'var(--surface-2, var(--bg))', padding: '8px 12px', borderRadius: 6,
@@ -485,16 +498,30 @@ export default function DataCleanupSection() {
La fiche plateforme "{purgePlat.nom}" est conservée. Cette opération ne peut pas être annulée.
</p>
<div style={{ margin: '0 0 20px' }}>
<label style={{ display: 'block', fontSize: 'var(--fs-sm)', fontWeight: 500, marginBottom: 6 }}>
Pour confirmer, retapez le nom exact de la plateforme : <strong>{purgePlat.nom}</strong>
<label style={{ display: 'block', fontSize: 'var(--fs-sm)', fontWeight: 500, marginBottom: 8 }}>
Pour confirmer, retapez le code affiché ci-dessous :
</label>
<div style={{
textAlign: 'center', margin: '0 0 14px', padding: '14px 10px',
background: 'var(--surface-2, var(--bg))', border: '1px dashed var(--danger, #ef4444)',
borderRadius: 8,
}}>
<span style={{
fontFamily: 'monospace', fontSize: 30, fontWeight: 700,
letterSpacing: 8, color: 'var(--danger, #ef4444)',
}}>
{purgePin}
</span>
</div>
<input
type="text"
inputMode="numeric"
maxLength={6}
value={purgeConfirmText}
onChange={e => setPurgeConfirmText(e.target.value)}
placeholder={purgePlat.nom}
onChange={e => setPurgeConfirmText(e.target.value.replace(/\D/g, '').slice(0, 6))}
placeholder="000000"
disabled={loadingPurge}
style={{ width: '100%' }}
style={{ width: '100%', textAlign: 'center', fontFamily: 'monospace', fontSize: 18, letterSpacing: 4 }}
/>
</div>
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
@@ -502,7 +529,7 @@ export default function DataCleanupSection() {
<button
className="danger"
onClick={handlePurge}
disabled={loadingPurge || purgeConfirmText.trim() !== purgePlat.nom}
disabled={loadingPurge || purgeConfirmText.trim() !== purgePin}
>
{loadingPurge ? 'Suppression en cours…' : 'Confirmer la suppression'}
</button>