Correction de l'affichage en tant que mono détenteur
This commit is contained in:
@@ -132,6 +132,8 @@ export default function ComptesSection() {
|
||||
});
|
||||
};
|
||||
|
||||
const multiDetenteur = investisseurs.length > 1;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="card">
|
||||
@@ -154,7 +156,7 @@ export default function ComptesSection() {
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<th style={{ width: '14%' }}>Type</th>
|
||||
<th style={{ width: '22%' }}>Détenteur</th>
|
||||
{multiDetenteur && <th style={{ width: '22%' }}>Détenteur</th>}
|
||||
<th style={{ width: '16%' }}>Banque</th>
|
||||
<th style={{ width: '10%' }}>Exonération</th>
|
||||
<th style={{ width: 80 }} />
|
||||
@@ -162,7 +164,7 @@ export default function ComptesSection() {
|
||||
</thead>
|
||||
<tbody>
|
||||
{comptes.length === 0 && (
|
||||
<tr><td colSpan={6} className="text-muted" style={{ textAlign: 'center', fontStyle: 'italic' }}>
|
||||
<tr><td colSpan={multiDetenteur ? 6 : 5} className="text-muted" style={{ textAlign: 'center', fontStyle: 'italic' }}>
|
||||
Aucun compte défini.
|
||||
</td></tr>
|
||||
)}
|
||||
@@ -172,7 +174,7 @@ export default function ComptesSection() {
|
||||
<tr key={c.id}>
|
||||
<td style={{ fontWeight: 500 }}>{c.nom}</td>
|
||||
<td><span className="badge">{TYPE_COMPTE_LABELS[c.type] ?? c.type}</span></td>
|
||||
<td>{inv ? memberLabel(inv) : <span className="text-muted">—</span>}</td>
|
||||
{multiDetenteur && <td>{inv ? memberLabel(inv) : <span className="text-muted">—</span>}</td>}
|
||||
<td>{c.banque || <span className="text-muted">—</span>}</td>
|
||||
<td>
|
||||
{c.exoneration_fiscale && c.exoneration_fiscale !== 'aucune' ? (
|
||||
|
||||
@@ -17,6 +17,12 @@ function dlBlob(content, filename, type) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
/** Date du jour au format YYYY-MM-DD, en heure locale (ne pas utiliser toISOString ici, décale d'un jour selon le fuseau). */
|
||||
function localToday() {
|
||||
const d = new Date();
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
const countryLabel = code => COUNTRIES.find(c => c.code === code)?.name ?? code ?? '—';
|
||||
const FISCALITE_LABELS = {
|
||||
flat_tax: 'Flat Tax',
|
||||
@@ -283,6 +289,13 @@ function PlatDetailPanel({ plat, onEdit }) {
|
||||
function PlatPickerModal({ open, onClose, referentiel, onSelect, onManual, err }) {
|
||||
const [search, setSearch] = useState('');
|
||||
const [domFilter, setDomFilter] = useState('all'); // 'all' | 'fr' | 'etr'
|
||||
const [confirming, setConfirming] = useState(null); // ref en cours de confirmation
|
||||
const [dateOuverture, setDateOuverture] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (open) { setConfirming(null); setDateOuverture(''); }
|
||||
}, [open]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
const q = search.trim().toLowerCase();
|
||||
@@ -298,6 +311,53 @@ function PlatPickerModal({ open, onClose, referentiel, onSelect, onManual, err }
|
||||
return f ? (LOGO_BASE + f) : null;
|
||||
};
|
||||
|
||||
/* ── Étape de confirmation : date d'ouverture du compte ── */
|
||||
if (confirming) {
|
||||
const img = imgFor(confirming);
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
title="Ajouter une plateforme"
|
||||
onClose={onClose}
|
||||
width={480}
|
||||
footer={
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
|
||||
<button type="button" className="ghost" onClick={() => setConfirming(null)}>← Retour</button>
|
||||
<button type="button" className="primary" onClick={() => onSelect(confirming, dateOuverture)}>
|
||||
Ajouter
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
{err && <div className="error">{err}</div>}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
{img
|
||||
? <img src={img} alt={confirming.nom} style={{ width: 44, height: 44, objectFit: 'contain', borderRadius: 8, flexShrink: 0 }} />
|
||||
: <div style={{ width: 44, height: 44, borderRadius: 8, flexShrink: 0, background: 'var(--surface-2)', border: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 18, color: 'var(--text-muted)' }}>🏦</div>
|
||||
}
|
||||
<div style={{ fontWeight: 600, fontSize: 'var(--fs-md)' }}>{confirming.nom}</div>
|
||||
</div>
|
||||
<p style={{ margin: 0, color: 'var(--text-muted)', fontSize: 'var(--fs-sm)', lineHeight: 1.5 }}>
|
||||
Pouvez-vous SVP préciser la date d'ouverture de votre compte sur cette plateforme ?
|
||||
</p>
|
||||
<div>
|
||||
<label style={{ display: 'block', fontWeight: 600, marginBottom: 4, fontSize: 'var(--fs-sm)' }}>
|
||||
Date d'ouverture du compte
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
autoFocus
|
||||
value={dateOuverture}
|
||||
onChange={e => setDateOuverture(e.target.value)}
|
||||
style={{ width: '100%', boxSizing: 'border-box' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
@@ -372,7 +432,7 @@ function PlatPickerModal({ open, onClose, referentiel, onSelect, onManual, err }
|
||||
<button
|
||||
key={r.id}
|
||||
type="button"
|
||||
onClick={() => onSelect(r)}
|
||||
onClick={() => { setConfirming(r); setDateOuverture(localToday()); }}
|
||||
style={{
|
||||
display: 'flex', flexDirection: 'column', alignItems: 'center',
|
||||
gap: 8, padding: '16px 10px 12px',
|
||||
@@ -779,7 +839,7 @@ export default function PlateformesSection() {
|
||||
};
|
||||
|
||||
/* ── Ajouter depuis le référentiel ──────────────────────────── */
|
||||
const addPlatFromRef = async (ref) => {
|
||||
const addPlatFromRef = async (ref, dateOuverture) => {
|
||||
try {
|
||||
await api.post('/plateformes', {
|
||||
nom: ref.nom,
|
||||
@@ -792,6 +852,7 @@ export default function PlateformesSection() {
|
||||
type_pret_defaut: ref.type_pret_defaut || null,
|
||||
freq_interets_defaut: ref.freq_interets_defaut || null,
|
||||
referentiel_id: ref.id,
|
||||
date_ouverture: dateOuverture || null,
|
||||
});
|
||||
setShowAddPicker(false);
|
||||
await load();
|
||||
@@ -942,6 +1003,8 @@ export default function PlateformesSection() {
|
||||
} catch (e) { setErr(e.message); }
|
||||
};
|
||||
|
||||
const multiDetenteur = new Set(plats.map(p => p.investisseur_id)).size > 1;
|
||||
|
||||
/* ── PFU CRUD ────────────────────────────────────────────────── */
|
||||
|
||||
|
||||
@@ -1000,14 +1063,14 @@ export default function PlateformesSection() {
|
||||
<th style={{ padding: '10px 8px', textAlign: 'left' }}>Domiciliation</th>
|
||||
<th style={{ padding: '10px 8px', textAlign: 'left' }}>Catégories</th>
|
||||
<th style={{ padding: '10px 8px', textAlign: 'left' }}>Secteurs</th>
|
||||
<th style={{ padding: '10px 8px', textAlign: 'left' }}>Détenteur</th>
|
||||
{multiDetenteur && <th style={{ padding: '10px 8px', textAlign: 'left' }}>Détenteur</th>}
|
||||
<th style={{ padding: '10px 16px', textAlign: 'center', width: 60 }}>Invest.</th>
|
||||
<th style={{ padding: '10px 8px', width: 40 }}></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{plats.length === 0 && (
|
||||
<tr><td colSpan={7} className="text-muted" style={{ textAlign: 'center', padding: 24 }}>Aucune plateforme</td></tr>
|
||||
<tr><td colSpan={multiDetenteur ? 8 : 7} className="text-muted" style={{ textAlign: 'center', padding: 24 }}>Aucune plateforme</td></tr>
|
||||
)}
|
||||
{plats.map((p, i) => {
|
||||
const imgSrc = p.icone_filename ? logoUrl(p.icone_filename) : p.logo_filename ? logoUrl(p.logo_filename) : null;
|
||||
@@ -1054,9 +1117,11 @@ export default function PlateformesSection() {
|
||||
{sects.length === 0 && <span style={{ fontSize: 11, color: 'var(--text-muted)' }}>—</span>}
|
||||
</div>
|
||||
</td>
|
||||
<td style={{ padding: '10px 8px', fontSize: 12, color: 'var(--text-muted)' }}>
|
||||
{inv ? memberLabel(inv) : '—'}
|
||||
</td>
|
||||
{multiDetenteur && (
|
||||
<td style={{ padding: '10px 8px', fontSize: 12, color: 'var(--text-muted)' }}>
|
||||
{inv ? memberLabel(inv) : '—'}
|
||||
</td>
|
||||
)}
|
||||
<td style={{ padding: '10px 16px', textAlign: 'center', fontWeight: 600,
|
||||
color: (p.nb_investissements ?? 0) > 0 ? 'var(--text)' : 'var(--text-muted)' }}>
|
||||
{p.nb_investissements ?? 0}
|
||||
|
||||
Reference in New Issue
Block a user