Repository navigation
Open
Labels
Description
<!doctype html>
<title>BGFI Bourse — Portail clients</title> <script src="https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"></script> <style> :root{--navy:#09233f;--blue:#1261a0;--cyan:#00a5b5;--bg:#f4f7fb;--ink:#172b43;--muted:#6c7b8e;--line:#dce5ef;--ok:#16824a;--warn:#b7791f;--danger:#b33a3a} *{box-sizing:border-box}body{margin:0;font-family:Inter,Segoe UI,Arial,sans-serif;color:var(--ink);background:var(--bg)} header{height:70px;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:space-between;padding:0 32px}header h1{font-size:20px;margin:0;font-weight:700}header small{opacity:.75} .layout{display:grid;grid-template-columns:250px 1fr;min-height:calc(100vh - 70px)}nav{background:#fff;border-right:1px solid var(--line);padding:24px 14px}nav button{width:100%;text-align:left;border:0;background:transparent;color:var(--ink);padding:13px 16px;border-radius:8px;font-size:14px;cursor:pointer;margin-bottom:5px}nav button.active,nav button:hover{background:#eaf3fb;color:var(--blue);font-weight:600}.nav-title{font-size:11px;text-transform:uppercase;color:var(--muted);letter-spacing:.1em;padding:12px 16px 8px} main{padding:30px;max-width:1500px;width:100%;margin:auto}.view{display:none}.view.active{display:block}.title-row{display:flex;align-items:center;justify-content:space-between;gap:15px;margin-bottom:22px}.title-row h2{margin:0;font-size:25px}.sub{color:var(--muted);margin-top:6px} .cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:22px}.card,.panel{background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 2px 8px #163f5b0b}.card{padding:20px}.card .label{color:var(--muted);font-size:12px}.card .value{font-size:27px;font-weight:700;margin-top:8px}.panel{padding:22px;margin-bottom:20px}.panel h3{margin:0 0 16px;font-size:16px} .toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.input{height:42px;border:1px solid var(--line);border-radius:8px;padding:0 12px;font-size:14px;background:#fff}.search{min-width:320px}.btn{height:42px;border:0;border-radius:8px;padding:0 16px;background:var(--blue);color:#fff;font-weight:600;cursor:pointer}.btn.secondary{background:#eaf3fb;color:var(--blue)}.btn.outline{background:#fff;color:var(--blue);border:1px solid #b7cee2}.btn.danger{background:#fff0f0;color:var(--danger)} table{border-collapse:collapse;width:100%;font-size:13px}th,td{text-align:left;padding:12px 10px;border-bottom:1px solid var(--line);vertical-align:middle}th{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;background:#fbfcfe}tr.client-row{cursor:pointer}tr.client-row:hover{background:#f4f9fd}.badge{display:inline-block;padding:4px 8px;border-radius:20px;font-size:11px;font-weight:600;background:#edf2f7;color:#536275}.badge.ok{background:#e8f7ef;color:var(--ok)}.badge.warn{background:#fff7df;color:var(--warn)} .profile{display:grid;grid-template-columns:1fr 1fr;gap:20px}.field-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}.field label{display:block;color:var(--muted);font-size:11px;margin-bottom:4px}.field strong{font-size:14px;word-break:break-word}.docs{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}.doc{border:1px solid var(--line);border-radius:9px;padding:13px}.doc-top{display:flex;align-items:center;justify-content:space-between;gap:8px}.doc-name{font-size:13px;font-weight:600}.doc-file{font-size:11px;color:var(--muted);margin:9px 0;min-height:15px;word-break:break-all}.doc input{display:none}.empty{padding:42px;text-align:center;color:var(--muted)}.drop{border:2px dashed #bdd2e3;border-radius:10px;padding:30px;text-align:center;color:var(--muted)}.drop.drag{background:#eef8fc;border-color:var(--cyan)}.toast{position:fixed;right:25px;bottom:25px;background:var(--navy);color:#fff;padding:13px 17px;border-radius:8px;display:none;z-index:5}.muted{color:var(--muted)} media(max-width:950px){.layout{grid-template-columns:1fr}nav{display:flex;overflow:auto;border-right:0;border-bottom:1px solid var(--line);padding:8px}nav button{min-width:max-content;margin:0}.nav-title{display:none}.cards{grid-template-columns:repeat(2,1fr)}.profile{grid-template-columns:1fr}main{padding:18px}.search{min-width:230px}} media print{header,nav,.no-print,.toolbar,.toast{display:none!important}.layout{display:block}main{padding:0}.panel{box-shadow:none;border:0}.profile{display:block}.profile>.panel{page-break-inside:avoid}.doc{break-inside:avoid}} </style>BGFI Bourse | Portail clients
Aucune base importéeNavigation
▦ Tableau de bord
⌕ Clients
◉ Fiche client
Administration
⇧ Importer la base
? Guide d’utilisation
Tableau de bord
Vue synthétique de votre portefeuille clients.
Clients chargés
0
Personnes physiques
0
Personnes morales
0
Dossiers complets
0%
Accès rapide
Rechercher un clientCharger la base Excel
Contrôle documentaire
Le logiciel suivra automatiquement les six pièces attendues : bulletin de souscription, preuve de règlement, pièce d’identité, RIB, fiche KYC et convention de service d’investissement.
<section class="view" id="clients"><div class="title-row"><div><h2>Clients</h2><div class="sub">Tapez un nom, un compte-titre ou une catégorie.</div></div></div><div class="panel"><div class="toolbar"><input id="search" class="input search" placeholder="Ex. ABA MICUE, compte-titre..." oninput="renderClients()"><select id="typeFilter" class="input" onchange="renderClients()"><option value="">Tous les types</option><option>Personne physique</option><option>Personne morale</option></select><span class="muted" id="resultCount"></span></div></div><div class="panel"><div id="clientTable"></div></div></section>
<section class="view" id="profile"><div class="title-row"><div><h2 id="profileTitle">Fiche client</h2><div class="sub" id="profileSub">Sélectionnez un client depuis la liste.</div></div><div class="toolbar no-print"><button class="btn outline" onclick="window.print()">Imprimer le dossier</button><button class="btn secondary" onclick="show('clients')">Retour aux clients</button></div></div><div id="profileBody" class="empty panel">Aucun client sélectionné.</div></section>
<section class="view" id="import"><div class="title-row"><div><h2>Importer la base clients</h2><div class="sub">Les données sont traitées dans votre navigateur pour ce prototype.</div></div></div><div class="panel"><div id="drop" class="drop"><p><strong>Déposez votre fichier Excel ici</strong></p><p>ou</p><label class="btn">Choisir un fichier<input id="fileInput" type="file" accept=".xlsx,.xls,.csv" onchange="importFile(this.files[0])"></label><p class="muted">Formats acceptés : .xlsx, .xls, .csv</p></div></div><div class="panel"><h3>Feuilles reconnues</h3><div id="sheetInfo" class="muted">Aucun fichier importé.</div></div></section>
<section class="view" id="help"><div class="title-row"><div><h2>Guide d’utilisation</h2><div class="sub">Les fonctions prévues pour l’équipe de gestion clients.</div></div></div><div class="panel"><h3>1. Charger la base</h3><p class="muted">Depuis « Importer la base », chargez le fichier Excel. La feuille « Personnes physiques » est utilisée automatiquement comme source principale, et les autres feuilles sont conservées comme références.</p><h3>2. Rechercher et ouvrir une fiche</h3><p class="muted">Dans « Clients », recherchez par nom ou compte-titre puis cliquez sur une ligne. La fiche regroupe les informations connues et le dossier numérique.</p><h3>3. Compléter et imprimer</h3><p class="muted">Ajoutez chaque document avec le bouton correspondant. Utilisez « Imprimer le dossier » pour générer une version imprimable de la fiche et du registre documentaire.</p></div></section>
✓ '+x+'
').join('');$('status').textContent=file.name+' — '+clients.length+' clients';updateKpis();toast('Base importée avec succès');show('clients')}catch(err){toast('Impossible de lire ce fichier Excel')}};reader.readAsArrayBuffer(file)}
function updateKpis(){const pp=clients.filter(x=>x.type==='Personne physique').length,pm=clients.filter(x=>x.type==='Personne morale').length;const complete=clients.length?Math.round(clients.filter(x=>docs.every(d=>(documents[x.account]||{})[d])).length/clients.length*100):0;$('kpiClients').textContent=clients.length.toLocaleString('fr-FR');$('kpiPP').textContent=pp.toLocaleString('fr-FR');$('kpiPM').textContent=pm.toLocaleString('fr-FR');$('kpiComplete').textContent=complete+'%'}
function renderClients(){const q=($('search')?.value||'').toLowerCase().trim(),type=$('typeFilter')?.value||'';const list=clients.filter(c=>(!q||JSON.stringify(c).toLowerCase().includes(q))&&(!type||c.type===type)).slice(0,300);$('resultCount').textContent=list.length+' résultat(s)';if(!list.length){$('clientTable').innerHTML='Aucun résultat. Importez la base ou modifiez votre recherche.
';return}let html='';list.forEach((c,i)=>{const count=docs.filter(d=>(documents[c.account]||{})[d]).length;html+=``});$('clientTable').innerHTML=html+'| Nom du client | Type | Compte-titre | Catégorie | Documents |
|---|---|---|---|---|
| ${esc(c.name)} | ${esc(c.type)} | ${esc(c.account)} | ${esc(c.category)} | ${count}/6 |
Informations client
'+fields.map(f=>`
${f[0]}${esc(f[1])}
`).join('')+'Dossier numérique (six pièces)
';const ds=documents[c.account]||{};docs.forEach((d,i)=>{const f=ds[d];html+=``});html+='
${i+1}. ${d}${f?'Reçu':'Manquant'}
${f?esc(f.name):'Aucun fichier'}
${f?'Remplacer':'Téléverser'}${f?`Retirer`:''}
Activity