diff --git a/public/app.js b/public/app.js index b3b687f..97daab4 100644 --- a/public/app.js +++ b/public/app.js @@ -7694,8 +7694,67 @@ window.toggleCustomAudio = (btn) => { // ============================================================ - // INVENTANDO HISTORIAS + // INVENTANDO HISTÓRIAS (ESTÚDIO PROFISSIONAL) // ============================================================ + const HISTORIA_TEMPLATES = { + arca: { + titulo: 'A Arca da Imaginação', + objeto: 'Arca Mágica de Madeira', + tema: 'As crianças encontram uma arca misteriosa no parquinho que se abre apenas quando todos dão as mãos e compartilham uma ideia criativa.', + estilo: 'Lúdico, Afetivo e Dialogado', + faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)', + visual: 'Cartoon colorido e acolhedor' + }, + horta: { + titulo: 'O Mistério da Horta Encantada', + objeto: 'Semente Brilhante de Girassol', + tema: 'A turma planta uma sementinha brilhante na horta da escola e descobre que ela cresce quando ouve canções de carinho e risadas.', + estilo: 'Contação Clássica com Suspense Leve', + faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)', + visual: 'Aquarela suave infantil' + }, + dinossauro: { + titulo: 'O Pequeno Dinossauro Amigo', + objeto: 'Pegada Colorida de Brinquedo', + tema: 'Um pequeno dinossauro verde e tímido aparece na hora do lanche procurando amigos para brincar de roda e desenhar.', + estilo: 'Lúdico, Afetivo e Dialogado', + faixa: 'Crianças bem pequenas (1 ano e 7 meses a 3 anos e 11 meses)', + visual: 'Cartoon colorido e acolhedor' + }, + chuva: { + titulo: 'O Dia em que a Chuva Dançou', + objeto: 'Galochas Amarelas Saltitantes', + tema: 'Em um dia chuvoso, as gotas batem na janela fazendo música e convidam as crianças para uma dança aconchegante dentro da sala.', + estilo: 'Roda de Conversa Interativa', + faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)', + visual: 'Aquarela suave infantil' + }, + bolhas: { + titulo: 'O Reino Mágico das Bolhas de Sabão', + objeto: 'Varinha de Fazer Bolhas Gigantes', + tema: 'Cada bolha de sabão que as crianças assopram no pátio leva um desejo de abraço e alegria até as nuvens coloridas.', + estilo: 'Lúdico, Afetivo e Dialogado', + faixa: 'Bebês (0 a 1 ano e 6 meses)', + visual: 'Giz de cera e textura lúdica' + }, + brinquedos: { + titulo: 'A Reunião Secreta dos Brinquedos', + objeto: 'Ursinho de Pano Guardião', + tema: 'Na hora do descanso, os brinquedos se organizam com muito capricho para esperar o acordar dos alunos com uma surpresa de blocos montados.', + estilo: 'Aventura e Descoberta na Escola', + faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)', + visual: 'Livro infantil clássico e detalhado' + }, + emocoes: { + titulo: 'O Monstrinho das Cores e dos Sentimentos', + objeto: 'Pote Brilhante das Emoções', + tema: 'Um monstrinho amigo muda de cor quando sente alegria (amarelo), calma (azul) ou saudade (rosa), ensinando a turma a expressar o que sente.', + estilo: 'Roda de Conversa Interativa', + faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)', + visual: 'Cartoon colorido e acolhedor' + } + }; + const barBtnHistoria = document.getElementById('barBtnHistoria'); const historiaModal = document.getElementById('historiaModal'); const btnCloseHistoriaModal = document.getElementById('btnCloseHistoriaModal'); @@ -7703,35 +7762,118 @@ window.toggleCustomAudio = (btn) => { const historiaHistoryModal = document.getElementById('historiaHistoryModal'); const btnCloseHistoriaHistory = document.getElementById('btnCloseHistoriaHistory'); + const historiaTemplateSelect = document.getElementById('historiaTemplateSelect'); + const historiaTurmaSelect = document.getElementById('historiaTurmaSelect'); + const historiaPersonagemInput = document.getElementById('historiaPersonagemInput'); + const historiaObjetoMagicoInput = document.getElementById('historiaObjetoMagicoInput'); const historiaFaixaEtaria = document.getElementById('historiaFaixaEtaria'); const historiaParagrafos = document.getElementById('historiaParagrafos'); - const historiaPersonagens = document.getElementById('historiaPersonagens'); const historiaEstilo = document.getElementById('historiaEstilo'); + const historiaEstiloVisual = document.getElementById('historiaEstiloVisual'); const historiaTemaInput = document.getElementById('historiaTemaInput'); const btnGenerateHistoria = document.getElementById('btnGenerateHistoria'); - const historiaGenerateLoader = document.getElementById('historiaGenerateLoader'); - const historiaResultArea = document.getElementById('historiaResultArea'); - const historiaTextOutput = document.getElementById('historiaTextOutput'); - const btnCopyHistoria = document.getElementById('btnCopyHistoria'); - const btnDownloadHistoriaPdf = document.getElementById('btnDownloadHistoriaPdf'); - let currentHistoria = ''; + // Elementos do Leitor e Visualizador + const historiaPlaceholderText = document.getElementById('historiaPlaceholderText'); + const historiaActiveBox = document.getElementById('historiaActiveBox'); + const historiaActiveTitle = document.getElementById('historiaActiveTitle'); + const historiaActiveSubtitle = document.getElementById('historiaActiveSubtitle'); + const historiaBnccBadge = document.getElementById('historiaBnccBadge'); - if (barBtnHistoria) { - barBtnHistoria.addEventListener('click', () => { - historiaModal.style.display = 'flex'; - historiaTemaInput.value = ''; - historiaResultArea.style.display = 'none'; - historiaGenerateLoader.style.display = 'none'; - btnGenerateHistoria.disabled = false; - currentHistoria = ''; + // Player de Áudio + const historiaAudioPlayerBox = document.getElementById('historiaAudioPlayerBox'); + const historiaAudioPlayer = document.getElementById('historiaAudioPlayer'); + const btnDownloadHistoriaAudio = document.getElementById('btnDownloadHistoriaAudio'); + const historiaWaveBars = document.querySelectorAll('.wave-bar-historia'); + + // Abas + const historiaContentTabs = document.getElementById('historiaContentTabs'); + const btnTabHistoriaCenas = document.getElementById('btnTabHistoriaCenas'); + const btnTabHistoriaTexto = document.getElementById('btnTabHistoriaTexto'); + const btnTabHistoriaAtividades = document.getElementById('btnTabHistoriaAtividades'); + const historiaCenasView = document.getElementById('historiaCenasView'); + const historiaTextoView = document.getElementById('historiaTextoView'); + const historiaAtividadesView = document.getElementById('historiaAtividadesView'); + + // Cenas Interativas + const btnPrevCena = document.getElementById('btnPrevCena'); + const btnNextCena = document.getElementById('btnNextCena'); + const historiaCenaIndicator = document.getElementById('historiaCenaIndicator'); + const historiaCenaTitle = document.getElementById('historiaCenaTitle'); + const historiaCenaText = document.getElementById('historiaCenaText'); + const historiaCenaImageContainer = document.getElementById('historiaCenaImageContainer'); + const historiaCenaImg = document.getElementById('historiaCenaImg'); + const btnGenerateSceneImage = document.getElementById('btnGenerateSceneImage'); + + // BNCC e Perguntas + const historiaBnccDesc = document.getElementById('historiaBnccDesc'); + const historiaPerguntasList = document.getElementById('historiaPerguntasList'); + + // Ações + const btnCopyActiveHistoria = document.getElementById('btnCopyActiveHistoria'); + const btnDownloadActiveHistoriaTxt = document.getElementById('btnDownloadActiveHistoriaTxt'); + const btnSendHistoriaToMusic = document.getElementById('btnSendHistoriaToMusic'); + const btnExportActiveHistoriaPdf = document.getElementById('btnExportActiveHistoriaPdf'); + + let currentHistoriaData = null; + let currentSceneIndex = 0; + + // Carregar turmas no select de histórias + async function loadTurmasForHistoria() { + if (!historiaTurmaSelect) return; + try { + const res = await fetch('/api/turmas'); + if (res.ok) { + const turmas = await res.json(); + historiaTurmaSelect.innerHTML = ''; + turmas.forEach(t => { + const opt = document.createElement('option'); + opt.value = t.id; + opt.textContent = `${t.nome} (${t.ano_letivo || '2026'})`; + historiaTurmaSelect.appendChild(opt); + }); + } + } catch (e) { + console.warn('Erro ao carregar turmas para histórias:', e); + } + } + + // Mudança de template + if (historiaTemplateSelect) { + historiaTemplateSelect.addEventListener('change', () => { + const key = historiaTemplateSelect.value; + if (key && HISTORIA_TEMPLATES[key]) { + const tpl = HISTORIA_TEMPLATES[key]; + historiaTemaInput.value = tpl.tema; + if (historiaObjetoMagicoInput) historiaObjetoMagicoInput.value = tpl.objeto; + if (historiaEstilo) historiaEstilo.value = tpl.estilo; + if (historiaFaixaEtaria) historiaFaixaEtaria.value = tpl.faixa; + if (historiaEstiloVisual) historiaEstiloVisual.value = tpl.visual; + } }); } - if (btnCloseHistoriaModal) historiaModal.addEventListener('click', (e) => { if(e.target === historiaModal) historiaModal.style.display = 'none'; }); - if (btnCloseHistoriaModal) btnCloseHistoriaModal.addEventListener('click', () => historiaModal.style.display = 'none'); - + // Abertura do Modal + if (barBtnHistoria) { + barBtnHistoria.addEventListener('click', () => { + historiaModal.style.display = 'flex'; + loadTurmasForHistoria(); + if (!currentHistoriaData) { + if (historiaPlaceholderText) historiaPlaceholderText.style.display = 'block'; + if (historiaActiveBox) historiaActiveBox.style.display = 'none'; + if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'none'; + if (historiaContentTabs) historiaContentTabs.style.display = 'none'; + } + }); + } + + if (btnCloseHistoriaModal) { + historiaModal.addEventListener('click', (e) => { if (e.target === historiaModal) historiaModal.style.display = 'none'; }); + btnCloseHistoriaModal.addEventListener('click', () => historiaModal.style.display = 'none'); + } + + // Histórico if (btnOpenHistoriaHistory) { btnOpenHistoriaHistory.addEventListener('click', () => { historiaHistoryModal.style.display = 'flex'; @@ -7739,93 +7881,358 @@ window.toggleCustomAudio = (btn) => { }); } if (btnCloseHistoriaHistory) btnCloseHistoriaHistory.addEventListener('click', () => historiaHistoryModal.style.display = 'none'); - historiaHistoryModal.addEventListener('click', (e) => { if(e.target === historiaHistoryModal) historiaHistoryModal.style.display = 'none'; }); + historiaHistoryModal.addEventListener('click', (e) => { if (e.target === historiaHistoryModal) historiaHistoryModal.style.display = 'none'; }); + // Alternância de Abas + function switchHistoriaTab(tab) { + [btnTabHistoriaCenas, btnTabHistoriaTexto, btnTabHistoriaAtividades].forEach(b => { + if (b) { + b.classList.remove('active'); + b.style.background = 'transparent'; + b.style.color = 'var(--text-secondary)'; + } + }); + if (historiaCenasView) historiaCenasView.style.display = 'none'; + if (historiaTextoView) historiaTextoView.style.display = 'none'; + if (historiaAtividadesView) historiaAtividadesView.style.display = 'none'; + + if (tab === 'cenas') { + if (btnTabHistoriaCenas) { + btnTabHistoriaCenas.classList.add('active'); + btnTabHistoriaCenas.style.background = 'rgba(16,185,129,0.15)'; + btnTabHistoriaCenas.style.color = '#34d399'; + } + if (historiaCenasView) historiaCenasView.style.display = 'flex'; + } else if (tab === 'texto') { + if (btnTabHistoriaTexto) { + btnTabHistoriaTexto.classList.add('active'); + btnTabHistoriaTexto.style.background = 'rgba(16,185,129,0.15)'; + btnTabHistoriaTexto.style.color = '#34d399'; + } + if (historiaTextoView) historiaTextoView.style.display = 'block'; + } else if (tab === 'atividades') { + if (btnTabHistoriaAtividades) { + btnTabHistoriaAtividades.classList.add('active'); + btnTabHistoriaAtividades.style.background = 'rgba(16,185,129,0.15)'; + btnTabHistoriaAtividades.style.color = '#34d399'; + } + if (historiaAtividadesView) historiaAtividadesView.style.display = 'flex'; + } + } + + if (btnTabHistoriaCenas) btnTabHistoriaCenas.addEventListener('click', () => switchHistoriaTab('cenas')); + if (btnTabHistoriaTexto) btnTabHistoriaTexto.addEventListener('click', () => switchHistoriaTab('texto')); + if (btnTabHistoriaAtividades) btnTabHistoriaAtividades.addEventListener('click', () => switchHistoriaTab('atividades')); + + // Renderizar Cena Atual + function renderCurrentScene() { + if (!currentHistoriaData || !currentHistoriaData.cenas || currentHistoriaData.cenas.length === 0) return; + const total = currentHistoriaData.cenas.length; + if (currentSceneIndex < 0) currentSceneIndex = 0; + if (currentSceneIndex >= total) currentSceneIndex = total - 1; + + const cena = currentHistoriaData.cenas[currentSceneIndex]; + if (historiaCenaIndicator) historiaCenaIndicator.textContent = `Cena ${currentSceneIndex + 1} de ${total}`; + if (historiaCenaTitle) historiaCenaTitle.textContent = cena.titulo || `Ato ${currentSceneIndex + 1}`; + if (historiaCenaText) historiaCenaText.textContent = cena.texto || ''; + + // Imagem da cena + if (cena.imageUrl) { + if (historiaCenaImg) historiaCenaImg.src = cena.imageUrl; + if (historiaCenaImageContainer) historiaCenaImageContainer.style.display = 'block'; + if (btnGenerateSceneImage) btnGenerateSceneImage.innerHTML = '🔄 Regenerar Ilustração'; + } else { + if (historiaCenaImageContainer) historiaCenaImageContainer.style.display = 'none'; + if (btnGenerateSceneImage) btnGenerateSceneImage.innerHTML = '🎨 Gerar Ilustração'; + } + + if (btnPrevCena) btnPrevCena.disabled = currentSceneIndex === 0; + if (btnNextCena) btnNextCena.disabled = currentSceneIndex === total - 1; + } + + if (btnPrevCena) { + btnPrevCena.addEventListener('click', () => { + if (currentSceneIndex > 0) { + currentSceneIndex--; + renderCurrentScene(); + } + }); + } + + if (btnNextCena) { + btnNextCena.addEventListener('click', () => { + if (currentHistoriaData && currentHistoriaData.cenas && currentSceneIndex < currentHistoriaData.cenas.length - 1) { + currentSceneIndex++; + renderCurrentScene(); + } + }); + } + + // Gerar Ilustração da Cena Atual + if (btnGenerateSceneImage) { + btnGenerateSceneImage.addEventListener('click', async () => { + if (!currentHistoriaData || !currentHistoriaData.cenas) return; + const cena = currentHistoriaData.cenas[currentSceneIndex]; + if (!cena) return; + + const originalBtnHtml = btnGenerateSceneImage.innerHTML; + btnGenerateSceneImage.disabled = true; + btnGenerateSceneImage.innerHTML = '⏳ Ilustrando...'; + + try { + const res = await fetch('/api/historias/scene-image', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + prompt: cena.promptImagem || cena.texto || 'Cute children book illustration', + estiloVisual: currentHistoriaData.estiloVisual || 'Cartoon colorido', + cenaNumero: currentSceneIndex + 1 + }) + }); + + const data = await res.json(); + if (res.ok && data.imageUrl) { + cena.imageUrl = data.imageUrl; + renderCurrentScene(); + showToast('Ilustração da cena criada com sucesso!', 'success'); + } else { + showToast(data.error || 'Erro ao gerar ilustração.', 'error'); + } + } catch (err) { + showToast('Erro ao conectar com gerador de ilustração.', 'error'); + } finally { + btnGenerateSceneImage.disabled = false; + btnGenerateSceneImage.innerHTML = originalBtnHtml; + } + }); + } + + // Gerar História Completa if (btnGenerateHistoria) { btnGenerateHistoria.addEventListener('click', async () => { const tema = historiaTemaInput.value.trim(); if (!tema) { - showToast('Por favor, informe o tema da história.', 'error'); + showToast('Por favor, informe o tema ou enredo da história.', 'error'); return; } btnGenerateHistoria.disabled = true; - historiaResultArea.style.display = 'none'; - historiaGenerateLoader.style.display = 'flex'; + if (historiaGenerateLoader) historiaGenerateLoader.style.display = 'flex'; + if (historiaPlaceholderText) historiaPlaceholderText.style.display = 'none'; try { const response = await fetch('/api/historias/generate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - faixaEtaria: historiaFaixaEtaria.value, - paragrafos: historiaParagrafos.value, - personagens: historiaPersonagens.value, - estilo: historiaEstilo.value, - tema: tema + tema: tema, + faixaEtaria: historiaFaixaEtaria ? historiaFaixaEtaria.value : 'Crianças pequenas', + paragrafos: historiaParagrafos ? historiaParagrafos.value : '3', + estilo: historiaEstilo ? historiaEstilo.value : 'Lúdico', + estiloVisual: historiaEstiloVisual ? historiaEstiloVisual.value : 'Cartoon colorido', + personagemPrincipal: historiaPersonagemInput ? historiaPersonagemInput.value.trim() : '', + objetoMagico: historiaObjetoMagicoInput ? historiaObjetoMagicoInput.value.trim() : '', + turmaId: historiaTurmaSelect ? historiaTurmaSelect.value : null }) }); const data = await response.json(); - - if (response.ok) { - currentHistoria = data.historia; - historiaTextOutput.innerHTML = window.marked ? marked.parse(currentHistoria) : currentHistoria; - historiaResultArea.style.display = 'flex'; + + if (response.ok && data.success) { + currentHistoriaData = data; + currentSceneIndex = 0; + + // Header + if (historiaActiveTitle) historiaActiveTitle.textContent = data.titulo || 'História Mágica'; + if (historiaActiveSubtitle) { + historiaActiveSubtitle.textContent = `Personagem: ${data.personagemPrincipal || 'Turma'} • ${data.cenas ? data.cenas.length : 3} Cenas • ${data.duracaoLeitura || '3 min'}`; + } + if (historiaBnccBadge) { + historiaBnccBadge.textContent = `BNCC: ${data.bnccCampos || 'EI02EF04 / EI03EF05'}`; + historiaBnccBadge.style.display = 'inline-block'; + } + + // Player de Áudio + if (data.audioUrl) { + if (historiaAudioPlayer) historiaAudioPlayer.src = data.audioUrl; + if (btnDownloadHistoriaAudio) btnDownloadHistoriaAudio.href = data.audioUrl; + if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'flex'; + + if (historiaAudioPlayer) { + historiaAudioPlayer.onplay = () => historiaWaveBars.forEach(b => b.classList.add('wave-active')); + historiaAudioPlayer.onpause = () => historiaWaveBars.forEach(b => b.classList.remove('wave-active')); + historiaAudioPlayer.onended = () => historiaWaveBars.forEach(b => b.classList.remove('wave-active')); + } + } else { + if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'none'; + } + + // Abas & Visualização + if (historiaContentTabs) historiaContentTabs.style.display = 'flex'; + if (historiaActiveBox) historiaActiveBox.style.display = 'flex'; + + // Texto completo + if (historiaTextoView) historiaTextoView.textContent = data.historiaCompleta || ''; + + // Atividades e BNCC + if (historiaBnccDesc) historiaBnccDesc.textContent = data.bnccCampos || 'EI02EF04 / EI03EF05 • Escuta, Fala, Pensamento e Imaginação'; + if (historiaPerguntasList) { + historiaPerguntasList.innerHTML = ''; + (data.perguntasCompreensao || []).forEach(p => { + const pEl = document.createElement('div'); + pEl.style.cssText = 'padding: 4px 0; border-bottom: 1px dashed rgba(255,255,255,0.05);'; + pEl.textContent = p; + historiaPerguntasList.appendChild(pEl); + }); + } + + renderCurrentScene(); + switchHistoriaTab('cenas'); + showToast('História inventada com sucesso!', 'success'); } else { - showToast(data.error || 'Erro ao inventar história.', 'error'); + showToast(data.error || 'Erro ao gerar história.', 'error'); } } catch (err) { - showToast('Erro de conexão.', 'error'); + showToast('Erro de conexão ao gerar história.', 'error'); } finally { - historiaGenerateLoader.style.display = 'none'; + if (historiaGenerateLoader) historiaGenerateLoader.style.display = 'none'; btnGenerateHistoria.disabled = false; } }); } - if (btnCopyHistoria) { - btnCopyHistoria.addEventListener('click', () => { - if (currentHistoria) { - navigator.clipboard.writeText(currentHistoria); + // Copiar História + if (btnCopyActiveHistoria) { + btnCopyActiveHistoria.addEventListener('click', () => { + if (currentHistoriaData && currentHistoriaData.historiaCompleta) { + navigator.clipboard.writeText(currentHistoriaData.historiaCompleta); showToast('História copiada para a área de transferência!', 'success'); } }); } - if (btnDownloadHistoriaPdf) { - btnDownloadHistoriaPdf.addEventListener('click', () => { - if (!currentHistoria) return; - const printWindow = window.open('', '_blank'); - printWindow.document.write(` - + // Baixar TXT + if (btnDownloadActiveHistoriaTxt) { + btnDownloadActiveHistoriaTxt.addEventListener('click', () => { + if (!currentHistoriaData) return; + const content = `========================================= +📖 ${currentHistoriaData.titulo || 'HISTÓRIA PEDAGÓGICA'} +========================================= +Personagem Principal: ${currentHistoriaData.personagemPrincipal || 'Turma'} +Objeto Mágico: ${currentHistoriaData.objetoMagico || 'Especial'} +BNCC: ${currentHistoriaData.bnccCampos || 'EI02EF04'} +Duração Estimada: ${currentHistoriaData.duracaoLeitura || '3 min'} + +--- HISTÓRIA COMPLETA --- +${currentHistoriaData.historiaCompleta || ''} + +--- PERGUNTAS PARA RODA DE CONVERSA --- +${(currentHistoriaData.perguntasCompreensao || []).join('\n')} + +Gerado por PedagogIA • Assistente da Professora Camila`; + + const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `${(currentHistoriaData.titulo || 'historia').toLowerCase().replace(/\s+/g, '_')}.txt`; + a.click(); + URL.revokeObjectURL(url); + }); + } + + // Musicar História + if (btnSendHistoriaToMusic) { + btnSendHistoriaToMusic.addEventListener('click', () => { + if (!currentHistoriaData) return; + const barBtnMusica = document.getElementById('barBtnMusica'); + const musicaTemaInput = document.getElementById('musicaTemaInput'); + historiaModal.style.display = 'none'; + if (barBtnMusica) barBtnMusica.click(); + if (musicaTemaInput) { + musicaTemaInput.value = `Canção sobre a história "${currentHistoriaData.titulo}": ${currentHistoriaData.objetoMagico || ''}, amizade e imaginação`; + } + showToast('História transferida para o Musicando Ideias!', 'info'); + }); + } + + // Exportar PDF Ilustrado + if (btnExportActiveHistoriaPdf) { + btnExportActiveHistoriaPdf.addEventListener('click', () => { + if (!currentHistoriaData) return; + const printWin = window.open('', '_blank'); + if (!printWin) { + showToast('Permita pop-ups para gerar o PDF.', 'warning'); + return; + } + + let cenasHtml = ''; + (currentHistoriaData.cenas || []).forEach((c, idx) => { + cenasHtml += ` +
${c.texto || ''}
+Carregando...
'; + listContainer.innerHTML = 'Carregando histórias...
'; try { const response = await fetch('/api/historias/list'); const data = await response.json(); @@ -7835,19 +8242,24 @@ window.toggleCustomAudio = (btn) => { const date = new Date(item.created_at).toLocaleString('pt-BR'); const div = document.createElement('div'); div.className = 'history-item-card'; - div.style.cssText = 'background: rgba(255,255,255,0.02); padding: 14px; border-radius: 8px; border: 1px solid var(--border-light); display: flex; flex-direction: column; gap: 8px; cursor: pointer; position: relative;'; + div.style.cssText = 'background: rgba(255,255,255,0.02); padding: 14px; border-radius: 8px; border: 1px solid var(--border-light); display: flex; flex-direction: column; gap: 6px; cursor: pointer; position: relative;'; div.innerHTML = `Tema: ${item.tema}
+Tema: ${item.tema}
`; div.addEventListener('click', async (e) => { if (e.target.closest('.btn-delete-historia')) { e.stopPropagation(); - if (confirm('Tem certeza que deseja excluir?')) { + if (confirm('Tem certeza que deseja excluir esta história?')) { try { const delRes = await fetch(`/api/historias/${item.id}`, { method: 'DELETE' }); if (delRes.ok) { showToast('História excluída.', 'success'); loadHistoriaHistory(); } @@ -7859,19 +8271,69 @@ window.toggleCustomAudio = (btn) => { const res = await fetch(`/api/historias/${item.id}`); const detail = await res.json(); if (res.ok) { - currentHistoria = detail.historia; - historiaTextOutput.innerHTML = window.marked ? marked.parse(currentHistoria) : currentHistoria; - historiaResultArea.style.display = 'flex'; + currentHistoriaData = { + id: detail.id, + titulo: detail.titulo || `História: ${detail.tema}`, + personagemPrincipal: detail.personagem_principal || '', + objetoMagico: detail.objeto_magico || '', + historiaCompleta: detail.historia || '', + cenas: typeof detail.cenas === 'string' ? JSON.parse(detail.cenas) : (detail.cenas || []), + perguntasCompreensao: typeof detail.perguntas_compreensao === 'string' ? JSON.parse(detail.perguntas_compreensao) : (detail.perguntas_compreensao || []), + bnccCampos: detail.bncc || 'EI02EF04 / EI03EF05', + duracaoLeitura: detail.duracao_leitura || '3 min', + complexidade: detail.complexidade || 'Lúdica', + audioUrl: detail.audio_url || null, + estiloVisual: detail.estilo_visual || 'Cartoon colorido' + }; + currentSceneIndex = 0; + + if (historiaActiveTitle) historiaActiveTitle.textContent = currentHistoriaData.titulo; + if (historiaActiveSubtitle) { + historiaActiveSubtitle.textContent = `Personagem: ${currentHistoriaData.personagemPrincipal || 'Turma'} • ${currentHistoriaData.cenas ? currentHistoriaData.cenas.length : 3} Cenas`; + } + if (historiaBnccBadge) { + historiaBnccBadge.textContent = `BNCC: ${currentHistoriaData.bnccCampos}`; + historiaBnccBadge.style.display = 'inline-block'; + } + + if (currentHistoriaData.audioUrl) { + if (historiaAudioPlayer) historiaAudioPlayer.src = currentHistoriaData.audioUrl; + if (btnDownloadHistoriaAudio) btnDownloadHistoriaAudio.href = currentHistoriaData.audioUrl; + if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'flex'; + } else { + if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'none'; + } + + if (historiaContentTabs) historiaContentTabs.style.display = 'flex'; + if (historiaActiveBox) historiaActiveBox.style.display = 'flex'; + if (historiaPlaceholderText) historiaPlaceholderText.style.display = 'none'; + + if (historiaTextoView) historiaTextoView.textContent = currentHistoriaData.historiaCompleta; + if (historiaBnccDesc) historiaBnccDesc.textContent = currentHistoriaData.bnccCampos; + if (historiaPerguntasList) { + historiaPerguntasList.innerHTML = ''; + (currentHistoriaData.perguntasCompreensao || []).forEach(p => { + const pEl = document.createElement('div'); + pEl.style.cssText = 'padding: 4px 0; border-bottom: 1px dashed rgba(255,255,255,0.05);'; + pEl.textContent = p; + historiaPerguntasList.appendChild(pEl); + }); + } + + renderCurrentScene(); + switchHistoriaTab('cenas'); historiaHistoryModal.style.display = 'none'; } - } catch (err) { showToast('Erro ao carregar.', 'error'); } + } catch (err) { showToast('Erro ao carregar história.', 'error'); } }); listContainer.appendChild(div); }); } else { - listContainer.innerHTML = 'Nenhum histórico.
'; + listContainer.innerHTML = 'Nenhuma história salva ainda.
'; } - } catch (err) { listContainer.innerHTML = 'Erro ao carregar.
'; } + } catch (err) { + listContainer.innerHTML = 'Erro ao carregar histórico de histórias.
'; + } } if (document.readyState === 'loading') { diff --git a/public/index.html b/public/index.html index f8f5b4a..e16c638 100644 --- a/public/index.html +++ b/public/index.html @@ -1208,88 +1208,274 @@