import { useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { api } from '../api.js'; import InvSelect from '../components/InvSelect.jsx'; import ConfirmModal from '../components/ConfirmModal.jsx'; import Modal from '../components/Modal.jsx'; import ResultBanner from '../components/ResultBanner.jsx'; import CountrySelect, { COUNTRIES, FlagIcon } from '../components/CountrySelect.jsx'; import { usePagination } from '../hooks/usePagination.js'; import Pagination from '../components/Pagination.jsx'; /* ── Icônes nav ───────────────────────────────────────────────── */ function IconDatabase() { return ; } function IconImage() { return ; } function IconLink() { return ; } function IconChevronLeft() { return ; } function IconEdit() { return ; } function IconTrash() { return ; } function IconPushSoft() { return ; } function IconPushForce() { return ; } function IconDownload() { return ; } function IconUpload() { return ; } /* ── Constantes ───────────────────────────────────────────────── */ const countryLabel = code => COUNTRIES.find(c => c.code === code)?.name ?? code ?? '—'; const FISCALITE_LABELS = { flat_tax: 'Flat tax (30%)', sans_fiscalite_locale: 'Sans fiscalité locale', avec_fiscalite_locale: 'Avec fiscalité locale' }; const EMPTY_REF = { nom: '', url: '', domiciliation: 'france', fiscalite: 'flat_tax', taux_fiscalite_locale: '', type_produit_fiscal: '2TT', methode_remboursement: 'portefeuille', type_pret_defaut: '', freq_interets_defaut: '', description: '', categories: [], categories_inv_ids: [], secteurs_inv_ids: [] }; /* ── Modal création / édition référentiel ─────────────────────── */ function RefModal({ row, onClose, onSaved }) { const isNew = !row?.id; const [catsInv, setCatsInv] = useState([]); const [secteursInv, setSecteursInv] = useState([]); const [err, setErr] = useState(null); const [saving, setSaving] = useState(false); const [form, setForm] = useState(isNew ? { ...EMPTY_REF } : { nom: row.nom || '', url: row.url || '', domiciliation: row.domiciliation || 'france', fiscalite: row.fiscalite || 'flat_tax', taux_fiscalite_locale: row.taux_fiscalite_locale != null ? String(row.taux_fiscalite_locale) : '', type_produit_fiscal: row.type_produit_fiscal || '2TT', methode_remboursement: row.methode_remboursement || 'portefeuille', type_pret_defaut: row.type_pret_defaut || '', freq_interets_defaut: row.freq_interets_defaut || '', description: row.description || '', categories: [], categories_inv_ids: (row.categories_inv || []).map(c => c.id), secteurs_inv_ids: (row.secteurs_inv || []).map(s => s.id), }); useEffect(() => { Promise.all([ api.get('/ref-categories'), api.get('/ref-secteurs'), ]).then(([cats, sects]) => { setCatsInv(cats); setSecteursInv(sects); }).catch(() => {}); }, []); // eslint-disable-line const set = (k, v) => setForm(f => ({ ...f, [k]: v })); const fiscalite = form.domiciliation === 'FR' ? 'flat_tax' : form.fiscalite; const handleSubmit = async (e) => { e.preventDefault(); if (!form.nom.trim()) { setErr('Le nom est requis.'); return; } setSaving(true); setErr(null); try { // Champs gérés par RefModal const ownFields = { nom: form.nom.trim(), url: form.url.trim() || null, domiciliation: form.domiciliation, fiscalite, taux_fiscalite_locale: fiscalite === 'avec_fiscalite_locale' && form.taux_fiscalite_locale !== '' ? Number(form.taux_fiscalite_locale) : null, type_produit_fiscal: form.type_produit_fiscal, methode_remboursement: form.methode_remboursement || 'portefeuille', type_pret_defaut: form.type_pret_defaut || null, freq_interets_defaut: form.freq_interets_defaut || null, description: form.description.trim() || null, categories_inv_ids: form.categories_inv_ids || [], secteurs_inv_ids: form.secteurs_inv_ids || [], }; if (isNew) { await api.post('/referentiel', { ...ownFields, categories: [], notation: [] }); } else { // Récupérer l'entrée courante pour préserver les champs du profil const current = await api.get(`/referentiel/${row.id}`); const payload = { ...ownFields, // Champs préservés — gérés uniquement par PlatformeProfile categories: current.categories ?? [], notation: current.notation ?? [], logo_filename: current.logo_filename ?? null, annee_creation: current.annee_creation ?? null, investisseurs_types: current.investisseurs_types ?? null, regulateur: current.regulateur ?? null, numero_licence: current.numero_licence ?? null, is_regule: current.is_regule ?? false, pays_inscription: current.pays_inscription ?? null, pays_siege: current.pays_siege ?? null, pays_operation: current.pays_operation ?? [], investissement_minimum: current.investissement_minimum ?? null, rendement_annonce: current.rendement_annonce ?? null, nb_investisseurs: current.nb_investisseurs ?? null, volume_total_finance: current.volume_total_finance ?? null, duree_moyenne_pret: current.duree_moyenne_pret ?? null, garantie_rachat: current.garantie_rachat ?? false, statistiques_publiques: current.statistiques_publiques ?? false, bonus_inscription: current.bonus_inscription ?? false, marche_secondaire: current.marche_secondaire ?? false, investissement_auto: current.investissement_auto ?? false, url_trustpilot: current.url_trustpilot ?? null, url_linkedin: current.url_linkedin ?? null, }; await api.put(`/referentiel/${row.id}`, payload); } onSaved(); onClose(); } catch (ex) { setErr(ex.message); } finally { setSaving(false); } }; return ( }>
set('nom', e.target.value)} placeholder="Ex : October, Lendosphere…" />
set('url', e.target.value)} placeholder="https://…" />
set('domiciliation', code)} showCode />
{form.domiciliation === 'FR' ? : }
{fiscalite === 'avec_fiscalite_locale' && (
set('taux_fiscalite_locale', e.target.value)} placeholder="Ex : 15" />
)}