SIGE · O Reformado
`); } // ─── BOLSAS ─── pages.bolsas = ()=>{ const bolsas=DB.get('bolsas')||[]; const est=DB.get('estudantes')||[]; const totalBolsas=bolsas.reduce((s,b)=>s+Number(b.valor),0); return `
${bolsas.length}
Bolsas activas
${fmt(totalBolsas)} MT
Valor mensal suportado
${[...new Set(bolsas.map(b=>b.parceiro))].length}
Parceiros financiadores
Bolsas e Parcerias
${bolsas.length?bolsas.map(b=>{const e=est.find(x=>x.id===b.estudante_id);return``;}).join(''):''}
EstudanteParceiroTipoValor/sem.Período
${escHtml(e?e.nome:'?')} ${escHtml(b.parceiro)} ${escHtml(b.tipo)} ${fmt(b.valor)} MT ${fmtDate(b.inicio)} → ${fmtDate(b.fim)}
🤝

Nenhuma bolsa registada.

`; }; function openBolsa(){ const est=DB.get('estudantes')||[]; const parceiros=['PRTS','Grace Missions','Igreja Reformada Central','Fundação Betel','Outro']; openModal('Nova Bolsa',`
`,``); } function saveBolsa(){ const eid=+document.getElementById('b-est').value; const par=document.getElementById('b-par').value; const val=+document.getElementById('b-val').value; if(!eid||!par||!val){toast('Preencha os campos obrigatórios','err');return;} const bolsas=DB.get('bolsas')||[]; bolsas.push({id:nextId(bolsas),estudante_id:eid,parceiro:par,tipo:document.getElementById('b-tipo').value,valor:val,inicio:document.getElementById('b-ini').value,fim:document.getElementById('b-fim').value,obs:document.getElementById('b-obs').value}); DB.set('bolsas',bolsas); closeModal();toast('Bolsa registada!');nav('bolsas'); } function delBolsa(id){ if(!confirm('Eliminar esta bolsa?')) return; DB.set('bolsas',(DB.get('bolsas')||[]).filter(b=>b.id!==id)); toast('Bolsa eliminada.','warn');nav('bolsas'); } // ─── MÓDULOS E NOTAS ─── pages.modulos = ()=>{ const mods=DB.get('modulos')||[]; const notas=DB.get('notas')||[]; const est=DB.get('estudantes')||[]; const equipa=DB.get('equipa')||[]; return `
Módulos
Notas
Módulos Curriculares
${mods.length?mods.map(m=>{const p=equipa.find(e=>e.id===m.professor_id);return``;}).join(''):''}
MóduloCursoSemestreProfessorCarga horáriaEstado
${escHtml(m.nome)} ${escHtml(m.curso)} Sem. ${m.semestre} ${p?escHtml(p.nome):'—'} ${m.carga}h ${m.estado}
📚

Nenhum módulo registado.

Lançamento de Notas
${notas.length?notas.map(n=>{const e=est.find(x=>x.id===n.estudante_id);const m=mods.find(x=>x.id===n.modulo_id);return``;}).join(''):''}
EstudanteMóduloSemestreNotaResultado
${escHtml(e?e.nome:'?')} ${escHtml(m?m.nome:'?')} ${escHtml(n.semestre)} ${n.nota} / 20 ${n.nota>=17?'Muito Bom':n.nota>=14?'Bom':n.nota>=10?'Suficiente':'Reprovado'}
📊

Nenhuma nota lançada.

`; }; function switchTab(tabsId, activeId){ const tabs=document.getElementById(tabsId); tabs.querySelectorAll('.tab').forEach((t,i)=>{t.classList.toggle('active',t.getAttribute('onclick')&&t.getAttribute('onclick').includes("'"+activeId+"'"));}); document.querySelectorAll('.tab-panel').forEach(p=>p.classList.remove('active')); document.getElementById(activeId).classList.add('active'); } function openModulo(id){ const mods=DB.get('modulos')||[]; const equipa=DB.get('equipa')||[]; const profs=equipa.filter(e=>['director','pedagogico','tutor'].includes(e.perfil)||true); const m=id?mods.find(x=>x.id===id):{}; openModal(id?'Editar Módulo':'Novo Módulo',`
`,``); } function saveModulo(id){ const nome=document.getElementById('m-nome').value.trim(); if(!nome){toast('Nome obrigatório','err');return;} const mods=DB.get('modulos')||[]; const obj={id:id||nextId(mods),nome,curso:document.getElementById('m-curso').value,semestre:+document.getElementById('m-sem').value,professor_id:+document.getElementById('m-prof').value||null,carga:+document.getElementById('m-carga').value,estado:document.getElementById('m-estado').value}; if(id){const i=mods.findIndex(m=>m.id===id);mods[i]=obj;}else mods.push(obj); DB.set('modulos',mods);closeModal();toast('Módulo guardado!');nav('modulos'); } function delModulo(id){if(!confirm('Eliminar este módulo?'))return;DB.set('modulos',(DB.get('modulos')||[]).filter(m=>m.id!==id));toast('Eliminado.','warn');nav('modulos');} function openNota(){ const est=DB.get('estudantes')||[]; const mods=DB.get('modulos')||[]; const sems=['2025/1','2025/2','2026/1','2026/2']; openModal('Lançar Nota',`
`,``); } function saveNota(){ const eid=+document.getElementById('n-est').value; const mid=+document.getElementById('n-mod').value; const nota=+document.getElementById('n-nota').value; if(!eid||!mid||isNaN(nota)||nota<0||nota>20){toast('Dados inválidos','err');return;} const notas=DB.get('notas')||[]; notas.push({id:nextId(notas),estudante_id:eid,modulo_id:mid,nota,semestre:document.getElementById('n-sem').value}); DB.set('notas',notas);closeModal();toast('Nota lançada!');nav('modulos'); } function delNota(id){if(!confirm('Eliminar esta nota?'))return;DB.set('notas',(DB.get('notas')||[]).filter(n=>n.id!==id));toast('Eliminado.','warn');nav('modulos');} // ─── TUTORIA ─── pages.tutoria = ()=>{ const sess=DB.get('sessoes_tutoria')||[]; const est=DB.get('estudantes')||[]; const equipa=DB.get('equipa')||[]; const tutores=equipa.filter(e=>e.perfil==='tutor'); return `
Sessões de Tutoria e Mentoria
${sess.length?[...sess].sort((a,b)=>new Date(b.data)-new Date(a.data)).map(s=>{ const e=est.find(x=>x.id===s.estudante_id); const t=equipa.find(x=>x.id===s.tutor_id); return``;}).join(''):''}
DataEstudanteTutorDuraçãoTemas abordadosAvaliação
${fmtDate(s.data)} ${escHtml(e?e.nome:'?')} ${escHtml(t?t.nome:'?')} ${s.duracao} min ${escHtml(s.temas)} ${escHtml(s.avaliacao)}
🌱

Nenhuma sessão de tutoria registada.

`; }; function openSessao(){ const est=DB.get('estudantes')||[]; const equipa=DB.get('equipa')||[]; const tutores=equipa.filter(e=>e.perfil==='tutor'); openModal('Registar Sessão de Tutoria',`
`,``); } function saveSessao(){ const eid=+document.getElementById('s-est').value; const tid=+document.getElementById('s-tut').value; const temas=document.getElementById('s-temas').value.trim(); if(!eid||!tid||!temas){toast('Preencha os campos obrigatórios','err');return;} const sess=DB.get('sessoes_tutoria')||[]; sess.push({id:nextId(sess),estudante_id:eid,tutor_id:tid,data:document.getElementById('s-data').value,duracao:+document.getElementById('s-dur').value,temas,notas:document.getElementById('s-notas').value,avaliacao:document.getElementById('s-aval').value}); DB.set('sessoes_tutoria',sess);closeModal();toast('Sessão registada!');nav('tutoria'); } function verSessao(id){ const s=DB.get('sessoes_tutoria').find(x=>x.id===id); const est=DB.get('estudantes').find(e=>e.id===s.estudante_id); const tutor=DB.get('equipa').find(e=>e.id===s.tutor_id); openModal('Detalhes da Sessão de Tutoria',` ${[['Estudante',est?est.nome:'?'],['Tutor',tutor?tutor.nome:'?'],['Data',fmtDate(s.data)],['Duração',s.duracao+' minutos'],['Avaliação',s.avaliacao]].map(([l,v])=>`
${l}${escHtml(String(v))}
`).join('')}
Temas abordados

${escHtml(s.temas)}

${s.notas?`
Notas do tutor

${escHtml(s.notas)}

`:''} `); } function delSessao(id){if(!confirm('Eliminar esta sessão?'))return;DB.set('sessoes_tutoria',(DB.get('sessoes_tutoria')||[]).filter(s=>s.id!==id));toast('Eliminado.','warn');nav('tutoria');} // ─── CALENDÁRIO ─── pages.calendario = ()=>{ const ev=DB.get('eventos')||[]; const tipos={intensiva:{label:'Semana Intensiva',badge:'badge-gold'},prazo:{label:'Prazo',badge:'badge-red'},exames:{label:'Exames',badge:'badge-blue'},outro:{label:'Outro',badge:'badge-gray'}}; return `
Calendário Académico
${[...ev].sort((a,b)=>new Date(a.inicio)-new Date(b.inicio)).map(e=>{const t=tipos[e.tipo]||tipos.outro;return``;}).join('')||''}
EventoTipoInícioFimLocal
${escHtml(e.titulo)} ${t.label} ${fmtDate(e.inicio)} ${fmtDate(e.fim)} ${escHtml(e.local||'—')}
🗓️

Nenhum evento no calendário.

`; }; function openEvento(){ openModal('Novo Evento',`
`,``); } function saveEvento(){ const titulo=document.getElementById('ev-title').value.trim(); const inicio=document.getElementById('ev-ini').value; if(!titulo||!inicio){toast('Título e data obrigatórios','err');return;} const ev=DB.get('eventos')||[]; ev.push({id:nextId(ev),titulo,tipo:document.getElementById('ev-tipo').value,local:document.getElementById('ev-local').value,inicio,fim:document.getElementById('ev-fim').value||inicio}); DB.set('eventos',ev);closeModal();toast('Evento adicionado!');nav('calendario'); } function delEvento(id){if(!confirm('Eliminar este evento?'))return;DB.set('eventos',(DB.get('eventos')||[]).filter(e=>e.id!==id));toast('Eliminado.','warn');nav('calendario');} // ─── EQUIPA ─── pages.equipa = ()=>{ const eq=DB.get('equipa')||[]; const perfis={director:'Director',secretario:'Secretário',pedagogico:'Pedagógico',financeiro:'Financeiro',tutor:'Tutor',professor:'Professor'}; return `
Equipa do Seminário
${eq.map(m=>``).join('')||''}
NomeFunçãoPerfilEmailTelefone
${escHtml(m.nome)} ${escHtml(m.papel)} ${perfis[m.perfil]||m.perfil} ${escHtml(m.email)} ${escHtml(m.tel)}
👥

Nenhum membro registado.

`; }; function openMembro(id){ const eq=DB.get('equipa')||[]; const m=id?eq.find(x=>x.id===id):{}; const perfis=[['director','Director'],['secretario','Secretário'],['pedagogico','Pedagógico'],['financeiro','Financeiro'],['tutor','Tutor'],['professor','Professor']]; openModal(id?'Editar Membro':'Novo Membro',`
`,``); } function saveMembro(id){ const nome=document.getElementById('mb-nome').value.trim(); if(!nome){toast('Nome obrigatório','err');return;} const eq=DB.get('equipa')||[]; const obj={id:id||nextId(eq),nome,papel:document.getElementById('mb-papel').value,perfil:document.getElementById('mb-perfil').value,email:document.getElementById('mb-email').value,tel:document.getElementById('mb-tel').value}; if(id){const i=eq.findIndex(e=>e.id===id);eq[i]=obj;}else eq.push(obj); DB.set('equipa',eq);closeModal();toast('Membro guardado!');nav('equipa'); } function delMembro(id){if(!confirm('Eliminar este membro?'))return;DB.set('equipa',(DB.get('equipa')||[]).filter(e=>e.id!==id));toast('Eliminado.','warn');nav('equipa');} // ─── RELATÓRIOS ─── pages.relatorios = ()=>{ return `
${[ ['📋','Listagem de Estudantes','Lista completa com curso, semestre e contactos','relatorioEstudantes'], ['💰','Relatório Financeiro','Todos os pagamentos com totais por semestre','relatorioFinanceiro'], ['📊','Notas por Módulo','Pauta completa de todos os módulos','relatorioNotas'], ['🌱','Relatório de Tutoria','Sessões de tutoria por tutor e estudante','relatorioTutoria'], ['🤝','Bolsas por Parceiro','Estudantes bolsistas e parceiros financiadores','relatorioBolsas'], ['🗓️','Calendário do Ano','Todos os eventos e semanas intensivas','relatorioCalendario'], ].map(([icon,title,desc,fn])=>`
${icon}
${title}
${desc}
`).join('')}
`; }; function printReport(title, html){ const win=window.open('','_blank','width=900,height=700'); win.document.write(`${title}${html}
O Reformado · SIGE · ${new Date().toLocaleDateString('pt-MZ')}