Feat: Criação do histórico, tabela no banco e geração nativa do Planejamento Mind Lab

This commit is contained in:
2026-06-05 18:51:05 +00:00
parent d74bb5e287
commit 5ea9c24ea0
4 changed files with 272 additions and 20 deletions
+146 -18
View File
@@ -6219,7 +6219,7 @@ document.addEventListener('DOMContentLoaded', () => {
}
if (btnGenerateMindLab) {
btnGenerateMindLab.addEventListener('click', () => {
btnGenerateMindLab.addEventListener('click', async () => {
const activeFaixa = document.querySelector('.btn-mindlab-faixa.active');
const activeJogoBtn = document.querySelector('.btn-mindlab-jogo.active');
const activeMetodo = document.querySelector('.btn-mindlab-metodo.active');
@@ -6236,25 +6236,153 @@ document.addEventListener('DOMContentLoaded', () => {
const duracaoStr = document.getElementById('mindLabDuracaoSelect').value;
const temaLivre = document.getElementById('mindLabTemaLivreInput').value.trim();
const promptText = `Atue como um especialista na metodologia educacional Mente Inovadora (Mind Lab). Crie um planejamento de aula super detalhado e engajador com os seguintes parâmetros:
- *Faixa Etária:* ${faixaStr}
- *Jogo de Raciocínio:* ${jogoStr}
- *Método Metacognitivo Foco:* ${metodoStr}
- *Foco de Transferência (Socioemocional):* ${focoStr}
- *Duração:* ${duracaoStr}${temaLivre ? '\n- *Tema Contextual:* ' + temaLivre : ''}
const btnG = document.getElementById('btnGenerateMindLab');
const loader = document.getElementById('mindLabGenerateLoader');
const resultArea = document.getElementById('mindLabResultArea');
const output = document.getElementById('mindLabOutput');
btnG.style.display = 'none';
loader.style.display = 'flex';
resultArea.style.display = 'none';
Por favor, estruture a aula com:
1. *Abertura (Contextualização):* Como introduzir o método e o tema.
2. *Jogo (Aplicação):* Orientações para a mediação durante a partida.
3. *Reflexão (Mediação Transcendental):* Perguntas provocativas para fazer as crianças refletirem.
4. *Transferência:* Como conectar o que aprenderam no jogo e o método escolhido (ex: Semáforo) com situações reais da vida deles.`;
mindLabModal.style.display = 'none';
if (typeof handleSendMessage === 'function') {
handleSendMessage(promptText);
} else {
console.error("handleSendMessage not found");
try {
const res = await fetch('/api/mindlab/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token')}` },
body: JSON.stringify({ faixa_etaria: faixaStr, jogo: jogoStr, metodo: metodoStr, foco: focoStr, duracao: duracaoStr, tema: temaLivre })
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || 'Erro na requisição');
output.innerHTML = typeof marked !== 'undefined' ? marked.parse(data.planejamento) : data.planejamento;
output.dataset.raw = data.planejamento;
resultArea.style.display = 'block';
btnG.style.display = 'flex';
btnG.innerHTML = '🧠 Criar Novo Planejamento';
} catch (err) {
alert('Erro ao gerar: ' + err.message);
btnG.style.display = 'flex';
} finally {
loader.style.display = 'none';
}
});
}
const btnCopyMindLab = document.getElementById('btnCopyMindLab');
if (btnCopyMindLab) {
btnCopyMindLab.addEventListener('click', () => {
const output = document.getElementById('mindLabOutput');
if (output && output.dataset.raw) {
navigator.clipboard.writeText(output.dataset.raw);
btnCopyMindLab.innerHTML = '<span class="material-icons" style="font-size:14px; vertical-align:middle;">check</span> Copiado!';
setTimeout(() => {
btnCopyMindLab.innerHTML = '<span class="material-icons" style="font-size:14px; vertical-align:middle;">content_copy</span> Copiar';
}, 2000);
}
});
}
const btnPdfMindLab = document.getElementById('btnPdfMindLab');
if (btnPdfMindLab) {
btnPdfMindLab.addEventListener('click', () => {
const output = document.getElementById('mindLabOutput');
if (output && output.dataset.raw && window.jspdf) {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(12);
doc.setFont("helvetica", "normal");
const lines = doc.splitTextToSize(output.dataset.raw.replace(/[#*]/g, ''), 180);
doc.text(lines, 15, 20);
doc.save('Planejamento_Mind_Lab.pdf');
} else {
alert('Carregando biblioteca PDF ou nenhum conteúdo para salvar.');
}
});
}
const btnOpenMindLabHistory = document.getElementById('btnOpenMindLabHistory');
const mindLabHistoryModal = document.getElementById('mindLabHistoryModal');
const btnCloseMindLabHistory = document.getElementById('btnCloseMindLabHistory');
const mindLabHistoryList = document.getElementById('mindLabHistoryList');
if (btnOpenMindLabHistory) {
btnOpenMindLabHistory.addEventListener('click', async () => {
mindLabHistoryModal.style.display = 'flex';
mindLabHistoryList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Carregando histórico...</div>';
try {
const res = await fetch('/api/mindlab/list', {
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
const data = await res.json();
mindLabHistoryList.innerHTML = '';
if (data.length === 0) {
mindLabHistoryList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Nenhum planejamento salvo ainda.</div>';
return;
}
data.forEach(item => {
const div = document.createElement('div');
div.style.background = 'var(--bg-tertiary)';
div.style.padding = '12px 15px';
div.style.borderRadius = '8px';
div.style.display = 'flex';
div.style.justifyContent = 'space-between';
div.style.alignItems = 'center';
div.innerHTML = `
<div>
<div style="font-weight: 600; font-size: 0.95rem; color: var(--text-primary);">🎲 ${item.jogo} - ${item.faixa_etaria}</div>
<div style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 4px;">🎯 ${item.foco}</div>
<div style="font-size: 0.75rem; color: var(--text-secondary); margin-top: 4px;">${new Date(item.created_at).toLocaleString()}</div>
</div>
<div style="display: flex; gap: 8px;">
<button class="btn-ver-mindlab btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.85rem; border-radius: 6px;">Ver</button>
<button class="btn-del-mindlab btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.85rem; border-radius: 6px; color: #ef4444; border-color: rgba(239, 68, 68, 0.3);">🗑️</button>
</div>
`;
mindLabHistoryList.appendChild(div);
});
document.querySelectorAll('.btn-ver-mindlab').forEach(btn => {
btn.addEventListener('click', async (e) => {
const id = e.target.dataset.id;
try {
const res = await fetch(`/api/mindlab/${id}`, {
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
const itemData = await res.json();
document.getElementById('mindLabOutput').innerHTML = typeof marked !== 'undefined' ? marked.parse(itemData.planejamento) : itemData.planejamento;
document.getElementById('mindLabOutput').dataset.raw = itemData.planejamento;
document.getElementById('mindLabResultArea').style.display = 'block';
mindLabHistoryModal.style.display = 'none';
document.getElementById('btnGenerateMindLab').style.display = 'flex';
} catch (err) { alert('Erro ao carregar planejamento.'); }
});
});
document.querySelectorAll('.btn-del-mindlab').forEach(btn => {
btn.addEventListener('click', async (e) => {
if(!confirm('Tem certeza que deseja apagar este planejamento?')) return;
const id = e.target.dataset.id;
try {
await fetch(`/api/mindlab/${id}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
e.target.closest('div[style*="var(--bg-tertiary)"]').remove();
} catch (err) { alert('Erro ao deletar.'); }
});
});
} catch (err) {
mindLabHistoryList.innerHTML = '<div style="color: #ef4444; padding: 20px;">Erro ao carregar histórico.</div>';
}
});
}
if (btnCloseMindLabHistory) {
btnCloseMindLabHistory.addEventListener('click', () => {
mindLabHistoryModal.style.display = 'none';
});
}
});