Réunions collaboratives

Organisez, suivez et documentez vos réunions

Réunions totales
En cours
Planifiées
Actions ouvertes
Chargement…
Chargement…
Chargement…
Chargement…
`n `; const w=window.open('','_blank'); w.document.write(html); w.document.close(); setTimeout(()=>{w.print();},500); }catch(e){DA.toast('Erreur export : '+e.message,{type:'danger'});} } async function exportResumeWord(rid){ try{ const [d,r]=await Promise.all([api('GET',`/reunions/${rid}`),api('GET',`/reunions/${rid}/resume`)]); const reunion=d.reunion;const resume=r.resume||{};const decisions=r.decisions||[]; const sujets=JSON.parse(resume.sujets||'[]'); const decs=JSON.parse(resume.decisions||'[]'); const actions=JSON.parse(resume.actions||'[]'); const html=`

Résumé de réunion — ${escH(reunion.titre)}

Date : ${fmtDate(reunion.date_debut)}

${sujets.length?`

Sujets abordés

`:''} ${decs.length?`

Décisions

`:''} ${actions.length?`

Actions

${actions.map(a=>``).join('')}
ActionResponsableÉchéance
${escH(a.titre||a)}${escH(a.responsable||'')}${escH(a.echeance||'')}
`:''} ${resume.notes?`

Notes

${escH(resume.notes).replace(/\n/g,'
')}

`:''} `; const blob=new Blob([''+html],{type:'application/msword'}); const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download=`resume-reunion-${rid}.doc`; a.click(); URL.revokeObjectURL(a.href); }catch(e){DA.toast('Erreur export : '+e.message,{type:'danger'});} } async function ajouterDecision(rid){ const titre=document.getElementById('new-dec-titre')?.value.trim(); if(!titre){DA.toast('Titre requis.',{type:'warning'});return;} const resp_id=document.getElementById('new-dec-resp-id')?.value; const type_suivi=document.getElementById('new-dec-type')?.value||'action'; const echeance=document.getElementById('new-dec-echeance')?.value||null; try{ await api('POST',`/reunions/${rid}/decisions`,{titre,type_suivi,responsable_id:resp_id?parseInt(resp_id):null,echeance}); DA.toast('Décision ajoutée !',{type:'success'}); ouvrirResume(rid); loadDecisions(); }catch(e){DA.toast(e.message,{type:'danger'});} } // ========= CRÉER RÉUNION MODAL ========= const pendingNewInvites=[]; document.getElementById('btn-nouvelle-reunion').addEventListener('click',()=>{ // Pré-remplir date à maintenant + 1h const now=new Date();now.setHours(now.getHours()+1);now.setMinutes(0,0,0); const fin=new Date(now);fin.setHours(fin.getHours()+1); document.getElementById('r-debut').value=now.toISOString().slice(0,16); document.getElementById('r-fin').value=fin.toISOString().slice(0,16); document.getElementById('modal-reunion').classList.add('open'); }); document.getElementById('close-modal-reunion').addEventListener('click',()=>document.getElementById('modal-reunion').classList.remove('open')); document.getElementById('close-modal-detail').addEventListener('click',()=>document.getElementById('modal-detail').classList.remove('open')); document.getElementById('close-modal-resume').addEventListener('click',()=>document.getElementById('modal-resume').classList.remove('open')); // Fermer si clic en dehors de la box ['modal-reunion','modal-detail','modal-resume'].forEach(id=>{ document.getElementById(id).addEventListener('click',function(e){if(e.target===this)this.classList.remove('open');}); }); // Recherche utilisateurs pour nouvelle réunion document.getElementById('r-search-users').addEventListener('input',async function(){ const q=this.value.trim(); if(q.length<2){document.getElementById('r-user-results').style.display='none';return;} try{ const{users}=await api('GET',`/users/search?q=${encodeURIComponent(q)}&limit=6`); const el=document.getElementById('r-user-results'); el.style.display='block'; el.innerHTML=users.map(u=>`
${avatarHTML(u,30)}${escH(u.prenom||'')} ${escH(u.nom||'')} ${escH(u.role||'')}
`).join(''); }catch(e){} }); function addNewInvite(id,prenom,nom){ if(pendingNewInvites.find(i=>i.id===id)) return; pendingNewInvites.push({id,prenom,nom}); document.getElementById('r-user-results').style.display='none'; document.getElementById('r-search-users').value=''; renderNewInvitesList(); } function removeNewInvite(id){ const i=pendingNewInvites.findIndex(x=>x.id===id); if(i>-1) pendingNewInvites.splice(i,1); renderNewInvitesList(); } function renderNewInvitesList(){ document.getElementById('r-invites-list').innerHTML=pendingNewInvites.map(i=>` ${escH(i.prenom)} ${escH(i.nom)} `).join(''); } document.getElementById('btn-creer-reunion').addEventListener('click',async()=>{ const titre=document.getElementById('r-titre').value.trim(); const date_debut=document.getElementById('r-debut').value; const errEl=document.getElementById('r-error'); if(!titre||!date_debut){errEl.textContent='Titre et date de début requis.';errEl.style.display='block';return;} errEl.style.display='none'; try{ const{id}=await api('POST','/reunions',{ titre, description:document.getElementById('r-description').value.trim()||null, type:document.getElementById('r-type').value, acces:document.getElementById('r-acces').value, date_debut, date_fin:document.getElementById('r-fin').value||null, ordre_du_jour:document.getElementById('r-odj').value.trim()||null, enregistrement_active:document.getElementById('r-enreg').checked }); // Inviter les participants sélectionnés if(pendingNewInvites.length){ await api('POST',`/reunions/${id}/invites`,{users:pendingNewInvites.map(i=>i.id)}); } DA.toast('Réunion créée avec succès !',{type:'success'}); document.getElementById('modal-reunion').classList.remove('open'); // Reset form ['r-titre','r-description','r-odj'].forEach(id=>document.getElementById(id).value=''); pendingNewInvites.length=0; renderNewInvitesList(); await loadReunions(); updateStats(); }catch(e){errEl.textContent=e.message||'Erreur.';errEl.style.display='block';} }); // Tabs document.querySelectorAll('.tab-btn').forEach(btn=>{ btn.addEventListener('click',()=>{ document.querySelectorAll('.tab-btn').forEach(b=>b.classList.remove('active')); document.querySelectorAll('.tab-pane').forEach(p=>p.classList.remove('active')); btn.classList.add('active'); document.getElementById('tab-'+btn.dataset.tab).classList.add('active'); // Sync sidebar document.querySelectorAll('.sidebar-tab').forEach(a=>a.classList.remove('active')); document.querySelector(`.sidebar-tab[data-tab="${btn.dataset.tab}"]`)?.classList.add('active'); }); }); document.querySelectorAll('.sidebar-tab').forEach(a=>{ a.addEventListener('click',e=>{ e.preventDefault(); document.querySelector(`.tab-btn[data-tab="${a.dataset.tab}"]`)?.click(); }); }); // Filtres document.getElementById('search-reunions').addEventListener('input',renderReunions); document.getElementById('filter-statut').addEventListener('change',renderReunions); document.getElementById('filter-dec-statut').addEventListener('change',renderDecisions); // Sidebar toggle (function(){ var toggle=document.getElementById('sidebar-toggle'); var close=document.getElementById('sidebar-close'); var back=document.getElementById('sidebar-backdrop'); var sb=document.querySelector('.sidebar'); function openSidebar(){sb?.classList.add('open');back?.classList.add('open');document.body.style.overflow='hidden';} function closeSidebar(){sb?.classList.remove('open');back?.classList.remove('open');document.body.style.overflow='';} toggle?.addEventListener('click',openSidebar); close?.addEventListener('click',closeSidebar); back?.addEventListener('click',closeSidebar); })(); init();