Implementação do CRUD de modelos de relatório e menu de emissão de relatórios compilados com filtros e exportação DOCX/PDF

This commit is contained in:
2026-05-28 11:45:11 +00:00
parent 80dd6ef9aa
commit 66cdf62d9b
3 changed files with 995 additions and 0 deletions
+165
View File
@@ -73,6 +73,22 @@
<span>Minhas Observações</span>
</button>
<!-- Botão: Emitir Relatório -->
<button class="btn-observacoes" id="btnEmitirRelatorio" style="border-color: var(--brand-green); color: var(--brand-green); background: rgba(16, 163, 127, 0.05);">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
</svg>
<span>Emitir Relatório</span>
</button>
<!-- Botão: Modelos de Relatório -->
<button class="btn-observacoes" id="btnModelosRelatorio">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<span>Modelos de Relatório</span>
</button>
<!-- Histórico de Conversas -->
<div class="chat-history" id="chatHistory">
<!-- Histórico filtrado/busca -->
@@ -449,6 +465,155 @@
</div>
</div>
<!-- Modal: Modelos de Relatório (CRUD Templates) -->
<div id="modelosRelatorioModal" class="settings-modal" style="display: none;">
<div class="settings-modal-content" style="max-width: 800px; width: 95%; max-height: 90vh; display: flex; flex-direction: column;">
<div class="settings-modal-header">
<h3>📋 Modelos de Relatório</h3>
<button id="btnCloseModelosModal" class="btn-close-modal">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="settings-modal-body" style="padding: 16px; overflow: hidden; display: flex; flex-direction: row; gap: 16px; flex: 1; min-height: 420px;">
<!-- Lado Esquerdo: Lista de Modelos -->
<div style="flex: 1; border-right: 1px solid var(--border-light); padding-right: 16px; display: flex; flex-direction: column; gap: 12px; overflow-y: auto;">
<div style="display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border-light); padding-bottom: 8px;">
<h4 style="margin: 0; color: var(--text-primary);">Modelos Salvos</h4>
<button id="btnCreateTemplate" style="background: var(--brand-green); color: white; border: none; padding: 6px 12px; border-radius: 6px; font-size: 0.85rem; font-weight: 600; cursor: pointer; transition: opacity 0.2s;">+ Novo Modelo</button>
</div>
<div id="templatesList" style="display: flex; flex-direction: column; gap: 8px;">
<!-- Carregado via JS -->
<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Carregando modelos...</div>
</div>
</div>
<!-- Lado Direito: Formulário de Cadastro/Edição -->
<div id="templateFormContainer" style="flex: 1.2; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; padding-left: 4px;">
<h4 id="templateFormTitle" style="margin: 0; color: var(--text-primary); border-bottom: 1px solid var(--border-light); padding-bottom: 8px;">Editar Modelo</h4>
<input type="hidden" id="templateFormId">
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.8rem; font-weight: 500;">Nome do Modelo</label>
<input type="text" id="templateFormNome" placeholder="Ex: Relatório Semanal de Desenvolvimento" class="obs-input" style="width: 100%;">
</div>
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.8rem; font-weight: 500;">Finalidade</label>
<input type="text" id="templateFormFinalidade" placeholder="Ex: Avaliar a evolução socioemocional..." class="obs-input" style="width: 100%;">
</div>
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.8rem; font-weight: 500;">Periodicidade / Frequência</label>
<select id="templateFormPeriodicidade" class="obs-select" style="width: 100%;">
<option value="Semanal">Semanal</option>
<option value="Mensal">Mensal</option>
<option value="Semestral">Semestral</option>
<option value="Anual">Anual</option>
<option value="Outro">Outro</option>
</select>
</div>
<div class="settings-group" style="flex: 1; display: flex; flex-direction: column; gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.8rem; font-weight: 500;">Estrutura do Relatório (Markdown / Diretrizes)</label>
<textarea id="templateFormEstrutura" placeholder="## Seção 1\n- Detalhe o comportamento...\n\n## Seção 2\n- Descreva a autonomia..." class="obs-input" style="width: 100%; flex: 1; min-height: 160px; font-family: monospace; resize: vertical; padding: 10px; line-height: 1.4;"></textarea>
</div>
<div style="display: flex; gap: 8px; justify-content: flex-end; border-top: 1px solid var(--border-light); padding-top: 12px; margin-top: auto;">
<button id="btnCancelTemplate" style="background: none; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 0.9rem;">Cancelar</button>
<button id="btnSaveTemplate" style="background: var(--brand-green); border: none; color: white; padding: 8px 16px; border-radius: 8px; font-weight: 600; cursor: pointer; font-size: 0.9rem;">Salvar Modelo</button>
</div>
</div>
</div>
</div>
</div>
<!-- Modal: Emitir Relatório (Geração com filtros e exportação) -->
<div id="emitirRelatorioModal" class="settings-modal" style="display: none;">
<div class="settings-modal-content" style="max-width: 800px; width: 95%; max-height: 90vh; display: flex; flex-direction: column;">
<div class="settings-modal-header">
<h3>📄 Emitir Relatório Pedagógico</h3>
<button id="btnCloseEmitirModal" class="btn-close-modal">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="settings-modal-body" style="padding: 16px; overflow: hidden; display: flex; flex-direction: column; gap: 12px; flex: 1;">
<!-- Filtros e Controles -->
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; background: var(--bg-secondary); padding: 12px; border-radius: 12px; border: 1px solid var(--border-light);">
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.78rem; font-weight: 600;">Criança</label>
<select id="emitirFilterCrianca" class="obs-select" style="padding: 6px 10px;">
<option value="">Selecione a criança</option>
</select>
</div>
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.78rem; font-weight: 600;">Data Início</label>
<input type="date" id="emitirFilterDataInicio" class="obs-input" style="padding: 5px 8px;">
</div>
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.78rem; font-weight: 600;">Data Fim</label>
<input type="date" id="emitirFilterDataFim" class="obs-input" style="padding: 5px 8px;">
</div>
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.78rem; font-weight: 600;">Tags</label>
<select id="emitirFilterTag" class="obs-select" style="padding: 6px 10px;">
<option value="">Todas as tags</option>
<option value="social">Social</option>
<option value="cognitivo">Cognitivo</option>
<option value="motor">Motor</option>
<option value="linguagem">Linguagem</option>
<option value="emocional">Emocional</option>
<option value="colaborativo">Colaborativo</option>
<option value="autônomo">Autônomo</option>
</select>
</div>
<div class="settings-group" style="gap: 4px;">
<label style="color: var(--text-secondary); font-size: 0.78rem; font-weight: 600;">Modelo / Template</label>
<select id="emitirFilterTemplate" class="obs-select" style="padding: 6px 10px;">
<option value="">Selecione o modelo</option>
</select>
</div>
</div>
<!-- Estatísticas e Botão de Ação -->
<div style="display: flex; justify-content: space-between; align-items: center; padding: 0 4px;">
<span id="emitirObsCountInfo" style="color: var(--text-secondary); font-size: 0.88rem; font-weight: 500;">Selecione uma criança para buscar observações...</span>
<button id="btnGenerateCompiledReport" disabled style="background: var(--brand-green); color: white; border: none; padding: 8px 18px; border-radius: 8px; font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: opacity 0.2s; opacity: 0.6;">
<span>Gerar Relatório com IA</span>
</button>
</div>
<!-- Visualizador / Pré-visualização do Relatório Gerado -->
<div style="flex: 1; border: 1px solid var(--border-light); border-radius: 12px; overflow: hidden; display: flex; flex-direction: column; background: var(--bg-secondary);">
<div style="padding: 8px 16px; border-bottom: 1px solid var(--border-light); background: var(--bg-primary); display: flex; justify-content: space-between; align-items: center;">
<span style="font-weight: 600; font-size: 0.88rem; color: var(--text-primary);">Visualização do Relatório</span>
<div style="display: flex; gap: 8px;">
<button id="btnExportDocx" disabled style="background: none; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 5px 12px; border-radius: 6px; font-size: 0.8rem; cursor: not-allowed; display: flex; align-items: center; gap: 4px; font-weight: 500; transition: all 0.2s;">
💾 DOCX
</button>
<button id="btnExportPdf" disabled style="background: none; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 5px 12px; border-radius: 6px; font-size: 0.8rem; cursor: not-allowed; display: flex; align-items: center; gap: 4px; font-weight: 500; transition: all 0.2s;">
🖨️ PDF
</button>
</div>
</div>
<div id="emitirReportPreviewArea" style="flex: 1; padding: 16px; overflow-y: auto; color: var(--text-primary); line-height: 1.6; font-size: 0.95rem;">
<div style="color: var(--text-secondary); text-align: center; margin-top: 50px;">
Escolha uma criança e um modelo de relatório para começar.
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bibliotecas externas para renderizar markdown e blocos de código -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>