Redator de SD - preparado para deploy
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Redator de SD — RMDS / SES-MG</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📋</text></svg>" />
|
||||
</head>
|
||||
<body>
|
||||
<header class="appbar">
|
||||
<h1>Redator de SD</h1>
|
||||
<span class="sub">RMDS · PE 29/2025 — SES-MG × Isis Saúde</span>
|
||||
<span class="spacer"></span>
|
||||
<span id="statusChip" class="chip-status">carregando…</span>
|
||||
<a href="#/" id="navHome" class="btn btn-sm">Nova SD</a>
|
||||
<a href="#/validar" id="navValidar" class="btn btn-sm">Validar JSON</a>
|
||||
<a href="#/base" id="navBase" class="btn btn-sm">Base de Conhecimento</a>
|
||||
<button id="btnTema" class="btn btn-sm" type="button" title="Tema">🌗</button>
|
||||
<button id="btnSair" class="btn btn-sm" hidden>Sair</button>
|
||||
</header>
|
||||
|
||||
<!-- Aviso de configuração -->
|
||||
<div id="avisoConfig" class="aviso" hidden>
|
||||
⚠ Chave de API não configurada. Copie <code>app\.env.example</code> para <code>app\.env</code>,
|
||||
preencha <code>ANTHROPIC_API_KEY</code> e reinicie o servidor.
|
||||
</div>
|
||||
|
||||
<!-- Login (usuário único) -->
|
||||
<main id="telaLogin" hidden>
|
||||
<form id="formLogin" class="panel login-box">
|
||||
<h2>Entrar</h2>
|
||||
<label>Usuário<br><input type="text" id="loginUsuario" autocomplete="username" required></label>
|
||||
<label>Senha<br><input type="password" id="loginSenha" autocomplete="current-password" required></label>
|
||||
<div id="loginErro" class="login-erro" hidden></div>
|
||||
<button type="submit" class="btn btn-primary" id="btnLogin">Entrar</button>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<!-- Tela inicial: lista + nova demanda -->
|
||||
<main id="telaHome" hidden>
|
||||
<section class="panel nova-demanda">
|
||||
<h2>Nova SD</h2>
|
||||
<p class="hint">Cole a demanda do jeito que ela chegou — trecho de ata, e-mail encaminhado, mensagem.
|
||||
Não precisa organizar. O redator lê, compara com a base e pergunta só o que faltar.</p>
|
||||
<textarea id="demandaInput" rows="5" placeholder="Ex.: a secretaria quer implementar um sistema de..."></textarea>
|
||||
<div class="btnrow">
|
||||
<button id="btnIniciar" class="btn btn-primary">Iniciar entrevista</button>
|
||||
<label class="sel-modelo">Modelo
|
||||
<select id="selModelo"></select>
|
||||
</label>
|
||||
</div>
|
||||
<p class="hint" style="margin:8px 0 0">O modelo fica fixo para a SD inteira (trocar no meio
|
||||
descartaria o cache da conversa). Lista configurável em <code>LLM_MODELOS</code> no .env.</p>
|
||||
</section>
|
||||
<section class="panel">
|
||||
<h2>SDs em andamento</h2>
|
||||
<div id="listaSds" class="lista-sds"></div>
|
||||
</section>
|
||||
<section class="panel">
|
||||
<h2>Saldo dos pools de UST</h2>
|
||||
<div id="saldosBox" class="saldos"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- Tela da entrevista: chat + painel -->
|
||||
<main id="telaConversa" class="conversa" hidden>
|
||||
<section class="coluna-chat">
|
||||
<div id="mensagens" class="mensagens"></div>
|
||||
<div id="opcoes" class="opcoes"></div>
|
||||
<form id="formMsg" class="form-msg">
|
||||
<textarea id="msgInput" rows="2" placeholder="Responda ao redator… (Enter envia, Shift+Enter quebra linha)"></textarea>
|
||||
<button type="submit" class="btn btn-primary" id="btnEnviarMsg">Enviar</button>
|
||||
</form>
|
||||
<div id="usoBox" class="uso"></div>
|
||||
</section>
|
||||
<aside class="coluna-painel" id="slotPainelConversa">
|
||||
<div id="painel">
|
||||
<div class="painel-vazio" id="painelVazio">O painel do documento aparece aqui assim que o redator
|
||||
registrar os primeiros campos da SD.</div>
|
||||
<div id="painelConteudo" hidden>
|
||||
<section class="pbloco" id="pResumo"></section>
|
||||
<section class="pbloco">
|
||||
<h3>Quadro de entregáveis</h3>
|
||||
<div id="pQuadro" class="twrap"></div>
|
||||
</section>
|
||||
<section class="pbloco">
|
||||
<h3>Trava de integridade — artefatos</h3>
|
||||
<div id="pArtefatos"></div>
|
||||
</section>
|
||||
<section class="pbloco">
|
||||
<h3>Checklist de validação</h3>
|
||||
<div id="pChecklist"></div>
|
||||
</section>
|
||||
<section class="pbloco">
|
||||
<h3>Pendências</h3>
|
||||
<ul id="pPendencias" class="pend-list"></ul>
|
||||
</section>
|
||||
<section class="pbloco" id="pExport">
|
||||
<h3>Fechamento</h3>
|
||||
<div id="pBloqueios" class="lock-msg"></div>
|
||||
<div class="btnrow">
|
||||
<button class="btn" id="btnDocumento">Documento / imprimir (PDF)</button>
|
||||
<button class="btn" id="btnBaixar">Baixar .json</button>
|
||||
<button class="btn btn-primary" id="btnEnviarSd">Marcar como enviada</button>
|
||||
</div>
|
||||
<p class="hint" style="margin-top:8px">O documento abre em uma aba pronta para imprimir
|
||||
(Ctrl+P → salvar como PDF). Enquanto houver pendência bloqueante, ele sai com marca de rascunho.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
|
||||
<!-- Validação de JSON externo -->
|
||||
<main id="telaValidar" class="conversa" hidden>
|
||||
<section class="coluna-chat">
|
||||
<div class="panel">
|
||||
<h2>Validar JSON externo</h2>
|
||||
<p class="hint">Cole aqui o JSON de uma SD que não nasceu neste app (ex.: redigida no Claude ou
|
||||
recebida de um colega). O app recalcula UST e datas, roda o checklist do contrato e libera o
|
||||
documento para impressão — sem salvar nada.</p>
|
||||
<textarea id="jsonExterno" rows="14" spellcheck="false"
|
||||
placeholder='Cole o JSON da SD (formato schema-sd.json)…'></textarea>
|
||||
<div id="validarErro" class="login-erro" hidden></div>
|
||||
<div class="btnrow" style="margin-top:10px">
|
||||
<button class="btn btn-primary" id="btnValidarJson">Validar</button>
|
||||
<button class="btn" id="btnImportarJson">Importar JSON</button>
|
||||
<button class="btn" id="btnLimparJson">Limpar</button>
|
||||
<button class="btn" id="btnVoltarValidar">Voltar</button>
|
||||
</div>
|
||||
<input type="file" id="arquivoJson" accept=".json,application/json" hidden>
|
||||
</div>
|
||||
</section>
|
||||
<aside class="coluna-painel" id="slotPainelValidar"></aside>
|
||||
</main>
|
||||
|
||||
<!-- Alimentar base de conhecimento: upload de SD real → extração → revisão → gravação -->
|
||||
<main id="telaBase" hidden>
|
||||
<section class="panel">
|
||||
<h2>Alimentar base de conhecimento</h2>
|
||||
<p class="hint">Envie o documento de uma SD real (<strong>.pdf</strong>, <strong>.md</strong> ou <strong>.txt</strong> —
|
||||
se estiver em .docx, exporte como PDF). O app lê o documento, extrai o registro estruturado
|
||||
(itens, UST por item, período, status) e sugere capacidades reutilizáveis. Nada é gravado
|
||||
sem a sua revisão abaixo.</p>
|
||||
<div class="btnrow">
|
||||
<button class="btn btn-primary" id="btnEscolherDoc">Enviar documento</button>
|
||||
<label class="sel-modelo">Modelo
|
||||
<select id="selModeloBase"></select>
|
||||
</label>
|
||||
<button class="btn" id="btnVoltarBase">Voltar</button>
|
||||
</div>
|
||||
<input type="file" id="arquivoDoc" accept=".pdf,.md,.txt,application/pdf,text/markdown,text/plain" hidden>
|
||||
<div id="baseErro" class="login-erro" hidden style="margin-top:10px"></div>
|
||||
<div id="baseExtraindo" class="hint" hidden style="margin-top:10px">⏳ Lendo o documento e extraindo o registro… isso leva de 30 segundos a 2 minutos.</div>
|
||||
<div id="baseUso" class="uso" style="margin-top:6px"></div>
|
||||
</section>
|
||||
|
||||
<section class="panel" id="baseRevisao" hidden>
|
||||
<h2>Revisão antes de gravar</h2>
|
||||
<div class="pbloco">
|
||||
<h3>Conferência (em código)</h3>
|
||||
<div id="baseConferencia"></div>
|
||||
</div>
|
||||
<div class="pbloco" id="baseObsBloco" hidden>
|
||||
<h3>Observações do extrator</h3>
|
||||
<ul id="baseObs" class="pend-list"></ul>
|
||||
</div>
|
||||
<div class="pbloco">
|
||||
<h3>Registro da SD (edite se necessário e reconfira)</h3>
|
||||
<textarea id="baseSdJson" rows="16" spellcheck="false"></textarea>
|
||||
</div>
|
||||
<div class="pbloco">
|
||||
<h3>Capacidades sugeridas (desmarque as que não devem entrar)</h3>
|
||||
<div id="baseCaps"></div>
|
||||
</div>
|
||||
<div class="btnrow">
|
||||
<button class="btn" id="btnReconferir">Reconferir</button>
|
||||
<button class="btn btn-primary" id="btnGravarBase">Gravar na base</button>
|
||||
</div>
|
||||
<div id="baseOk" class="lock-msg open" hidden style="margin-top:10px"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user