import { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { api } from '../api.js'; import InvSelect from '../components/InvSelect.jsx'; import { useAuth } from '../context/AuthContext.jsx'; import ResultBanner from '../components/ResultBanner.jsx'; import CountrySelect, { COUNTRIES, FlagIcon } from '../components/CountrySelect.jsx'; const LOGO_BASE = (import.meta.env.VITE_API_URL || '/api').replace(/\/api$/, '') + '/api/logos/'; const TYPES_INV = { p2p: 'Prêt P2P', dette: 'Dette', equity: 'Capitaux propres', tokenise: 'Tokenisé', achat_louer: 'Achat à louer', mini_obligations:'Mini-obligations', mixte: 'Mixte', }; const SECTEURS = { immobilier: 'Immobilier', pme: 'PME', startups: 'Startups', litige: 'Litige', energie: 'Énergie verte', sante_science: 'Santé & Science', logistique: 'Logistique', personnel: 'Prêts personnels', art: 'Art', autre: 'Autre', }; const INV_TYPES = { particulier: 'Particulier', entreprise: 'Entreprise', les_deux: 'Particulier & Entreprise', }; const countryLabel = code => COUNTRIES.find(c => c.code === code)?.name ?? code ?? '—'; // ── Composants helpers ──────────────────────────────────────────────────────── function SectionTitle({ children }) { return (
{children}
); } function KpiCell({ label, value, editing, input }) { return (
{label}
{editing ? input :
{value ?? 'N/A'}
}
); } function InfoRow({ label, value, editing, input }) { return (
{label} {editing ? input : {value ?? '—'} }
); } function FeatureRow({ label, field, data, editing, onChange }) { const val = !!(data?.[field]); return (
{editing ? ( ) : ( <>
{val ? : }
{label} )}
); } // ── Page principale ──────────────────────────────────────────────────────────── export default function PlatformeProfile() { const { id } = useParams(); const navigate = useNavigate(); const { isAdmin } = useAuth(); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [err, setErr] = useState(null); const [editing, setEditing] = useState(false); const [form, setForm] = useState(null); const [saving, setSaving] = useState(false); const [saveErr, setSaveErr] = useState(null); const [catsInv, setCatsInv] = useState([]); // categories_inv globales const [secteursInv, setSecteursInv] = useState([]); // secteurs_inv globaux useEffect(() => { load(); if (isAdmin) { api.get('/ref-categories').then(setCatsInv).catch(() => {}); api.get('/ref-secteurs').then(setSecteursInv).catch(() => {}); } }, [id]); async function load() { try { setLoading(true); const endpoint = isAdmin ? `/referentiel/${id}` : `/referentiel-public/${id}`; const d = await api.get(endpoint); setData(d); } catch (e) { setErr(e.message); } finally { setLoading(false); } } function startEdit() { const paysOp = Array.isArray(data.pays_operation) ? data.pays_operation.join(', ') : (data.pays_operation || ''); setForm({ ...data, pays_operation_str: paysOp, categories_inv_ids: (data.categories_inv || []).map(c => c.id), secteurs_inv_ids: (data.secteurs_inv || []).map(s => s.id), }); setEditing(true); setSaveErr(null); } function cancelEdit() { setEditing(false); setForm(null); } const setField = (key, val) => setForm(f => ({ ...f, [key]: val })); const setInput = key => e => setField(key, e.target.type === 'checkbox' ? e.target.checked : e.target.value); async function save() { setSaving(true); setSaveErr(null); try { const paysArr = form.pays_operation_str ? form.pays_operation_str.split(',').map(s => s.trim()).filter(Boolean) : []; const payload = { nom: form.nom, url: form.url || null, domiciliation: form.domiciliation, fiscalite: form.fiscalite, taux_fiscalite_locale: form.taux_fiscalite_locale !== '' && form.taux_fiscalite_locale != null ? Number(form.taux_fiscalite_locale) : null, type_produit_fiscal: form.type_produit_fiscal || '2TT', logo_filename: data.logo_filename ?? null, description: form.description || null, categories: data.categories || [], notation: data.notation || [], categories_inv_ids: form.categories_inv_ids || [], secteurs_inv_ids: form.secteurs_inv_ids || [], // Profil enrichi annee_creation: form.annee_creation ? Number(form.annee_creation) : null, investisseurs_types: form.investisseurs_types || null, regulateur: form.regulateur || null, numero_licence: form.numero_licence || null, is_regule: form.is_regule ? 1 : 0, pays_inscription: form.pays_inscription || null, pays_siege: form.pays_siege || null, pays_operation: paysArr, investissement_minimum: form.investissement_minimum !== '' && form.investissement_minimum != null ? Number(form.investissement_minimum) : null, rendement_annonce: form.rendement_annonce !== '' && form.rendement_annonce != null ? Number(form.rendement_annonce) : null, nb_investisseurs: form.nb_investisseurs !== '' && form.nb_investisseurs != null ? Number(form.nb_investisseurs) : null, volume_total_finance: form.volume_total_finance !== '' && form.volume_total_finance != null ? Number(form.volume_total_finance) : null, duree_moyenne_pret: form.duree_moyenne_pret !== '' && form.duree_moyenne_pret != null ? Number(form.duree_moyenne_pret) : null, garantie_rachat: form.garantie_rachat ? 1 : 0, statistiques_publiques: form.statistiques_publiques ? 1 : 0, bonus_inscription: form.bonus_inscription ? 1 : 0, marche_secondaire: form.marche_secondaire ? 1 : 0, investissement_auto: form.investissement_auto ? 1 : 0, url_trustpilot: form.url_trustpilot || null, url_linkedin: form.url_linkedin || null, }; const updated = await api.put(`/referentiel/${id}`, payload); setData(updated); setCatsInv(await api.get('/ref-categories').catch(() => catsInv)); setEditing(false); setForm(null); } catch (e) { setSaveErr(e.message); } finally { setSaving(false); } } if (loading) return
Chargement…
; if (err) return
{err}
; if (!data) return null; const d = editing ? form : data; const paysOp = Array.isArray(data.pays_operation) ? data.pays_operation : []; return (
{/* ── Breadcrumb ─────────────────────────────────────────────────────── */}
/ Référentiel / {data.nom}
{/* ── Hero ───────────────────────────────────────────────────────────── */}
{/* Logo */}
{data.logo_filename ? {data.nom} { e.currentTarget.style.display = 'none'; }} /> : {data.nom[0].toUpperCase()} }
{/* Titre + badges */}
{editing ? :

{data.nom}

} {data.is_regule ? ✓ Réglementé : isAdmin && Non réglementé } {data.domiciliation && ( {countryLabel(data.domiciliation)} )}
{editing ?