export const fmtEUR = (n) => (n == null ? '' : Number(n).toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' })); export const fmtNum = (n, digits = 2) => (n == null ? '' : Number(n).toLocaleString('fr-FR', { minimumFractionDigits: digits, maximumFractionDigits: digits })); export const fmtPct = (n) => (n == null ? '' : Number(n).toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' %'); export const fmtDate = (s) => { if (!s) return ''; const [y, m, d] = String(s).slice(0, 10).split('-'); return d ? `${d}/${m}/${y}` : s; }; export const today = () => new Date().toISOString().slice(0, 10); /* ── Membres / Investisseurs ───────────────────────────────── */ /** Nom affiché. * `nom` contient toujours le nom complet ("Olivier CROGUENNEC", "SCI Famille…"). * `prenom` est stocké séparément uniquement pour les initiales et le formulaire. */ export const memberDisplayName = (m) => m?.nom ?? ''; /** Label pour les selects : displayName + type_fiscal si entreprise */ export const memberLabel = (m) => { if (!m) return ''; const name = memberDisplayName(m); if (m.type === 'entreprise' && m.type_fiscal) return `${name} (${m.type_fiscal})`; return name; }; /* ── Statuts investissements ───────────────────────────────── */ export const STATUT_LABELS = { en_cours: 'En cours', rembourse: 'Remboursé', en_retard: 'En retard', procedure: 'Procédure', cloture: 'Clôturé', }; /** Retourne le libellé affiché d'un statut (première lettre majuscule). */ export const fmtStatut = (s) => STATUT_LABELS[s] ?? s; /** Initiales pour l'avatar (2 caractères max). * - Si prenom est renseigné : 1re lettre du prénom + 1re lettre du reste du nom complet * - Sinon (données migrées) : 1re lettre du 1er mot + 1re lettre du dernier mot du nom complet * Ex. prenom="Olivier" nom="Olivier CROGUENNEC" → "OC" * Ex. prenom=null nom="Marine CROGUENNEC" → "MC" */ export const memberInitials = (m) => { if (!m) return '?'; if (m.type === 'famille') { if (m.prenom) { const firstLetter = m.prenom[0]; const rest = m.nom.replace(m.prenom, '').trim(); const lastLetter = rest[0] || ''; return (firstLetter + lastLetter).toUpperCase(); } // prenom absent : découper le nom complet en mots const parts = m.nom.trim().split(/\s+/); if (parts.length >= 2) { return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase(); } return m.nom.slice(0, 2).toUpperCase(); } // Entreprise : deux premières lettres de la raison sociale return m.nom.slice(0, 2).toUpperCase(); };