import { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { fmtEUR } from '../utils/format.js'; /** * InvestissementSelect — combobox pour le champ "Investissement" de RembFormModal. * * Remplace le natif via CSS, ce qui produisait une liste déroulante démesurément haute * quand beaucoup d'investissements existent. * * Positionnement en `position: fixed` (calculé via getBoundingClientRect, comme InvSelect.jsx) — * pas en `position: absolute` — car ce champ est utilisé dans RembFormModal dont le conteneur * `.card` a `overflow: auto` (voir Modal.jsx) : un dropdown en absolute y serait rogné quand la * fenêtre est basse. Le dropdown bascule aussi au-dessus du champ s'il n'y a pas assez de place * en dessous, et se ferme au scroll/resize (repositionnement non géré en direct, comme InvSelect). * * Props : * value : '' | 'BONUS_PARRAINAGE' | 'BONUS_PLATEFORME' | 'INTERETS_PLATEFORME' | id (string/number) * onChange : (value) => void * options : investissementOptions — { id, plateforme_nom, nom_projet, montant_investi }[] */ export default function InvestissementSelect({ value, onChange, options = [], // Libellé du sentinel INTERETS_PLATEFORME (17/09/26, cf. RemboursementsSimple.jsx — // une distribution PE n'est pas un "intérêt" au sens crowdlending du terme ; la valeur // technique INTERETS_PLATEFORME/interets_plateforme reste inchangée, seul l'intitulé // affiché change). Par défaut, le libellé crowdlending d'origine. interetsPlateformeLabel = '🏦 Intérêts plateforme', }) { const [open, setOpen] = useState(false); const [dropPos, setDropPos] = useState({ left: 0, width: 0, maxHeight: 260, direction: 'down', top: 0, bottom: 0 }); const wrapRef = useRef(null); const triggerRef = useRef(null); const selectedOption = options.find(i => String(i.id) === String(value)); const label = value === 'BONUS_PARRAINAGE' ? '🎁 Bonus Parrainage' : value === 'BONUS_PLATEFORME' ? '🏆 Bonus Plateforme' : value === 'INTERETS_PLATEFORME' ? interetsPlateformeLabel : selectedOption ? `${selectedOption.plateforme_nom} — ${selectedOption.nom_projet} (${fmtEUR(selectedOption.montant_investi)})` : null; useLayoutEffect(() => { if (!open || !triggerRef.current) return; const rect = triggerRef.current.getBoundingClientRect(); const margin = 8; const spaceBelow = window.innerHeight - rect.bottom - margin; const spaceAbove = rect.top - margin; const desired = 260; // ~ moitié de la hauteur qu'affichait le