|
|
<!DOCTYPE html> |
|
|
<html lang="pt-BR"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Mapeamento de Argumentos - Processo Penal</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://unpkg.com/[email protected]"></script> |
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> |
|
|
<script> |
|
|
tailwind.config = { |
|
|
theme: { |
|
|
extend: { |
|
|
colors: { |
|
|
primary: '#2563eb', |
|
|
secondary: '#475569', |
|
|
danger: '#dc2626', |
|
|
success: '#16a34a', |
|
|
info: '#0891b2', |
|
|
warning: '#d97706', |
|
|
slate: { |
|
|
50: '#f8fafc', |
|
|
100: '#f1f5f9', |
|
|
200: '#e2e8f0', |
|
|
300: '#cbd5e1', |
|
|
400: '#94a3b8', |
|
|
500: '#64748b', |
|
|
600: '#475569', |
|
|
700: '#334155', |
|
|
800: '#1e293b', |
|
|
900: '#0f172a', |
|
|
}, |
|
|
gradient: { |
|
|
start: '#1e3c72', |
|
|
end: '#2a5298' |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
<style> |
|
|
.fade-in { |
|
|
animation: fadeIn 0.5s ease-in; |
|
|
} |
|
|
|
|
|
@keyframes fadeIn { |
|
|
from { opacity: 0; transform: translateY(10px); } |
|
|
to { opacity: 1; transform: translateY(0); } |
|
|
} |
|
|
|
|
|
.card-hover { |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.card-hover:hover { |
|
|
transform: translateY(-5px); |
|
|
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1) !important; |
|
|
} |
|
|
|
|
|
.badge { |
|
|
font-size: 0.75rem; |
|
|
padding: 0.25rem 0.5rem; |
|
|
border-radius: 9999px; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
.timeline::before { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
left: 20px; |
|
|
top: 0; |
|
|
bottom: 0; |
|
|
width: 2px; |
|
|
background-color: #e2e8f0; |
|
|
} |
|
|
|
|
|
.timeline-item::before { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
left: 17px; |
|
|
top: 8px; |
|
|
width: 8px; |
|
|
height: 8px; |
|
|
border-radius: 50%; |
|
|
background-color: #2563eb; |
|
|
border: 2px solid white; |
|
|
box-shadow: 0 0 0 2px #2563eb; |
|
|
} |
|
|
|
|
|
.draggable { |
|
|
cursor: grab; |
|
|
} |
|
|
|
|
|
.draggable:active { |
|
|
cursor: grabbing; |
|
|
} |
|
|
|
|
|
.dropzone { |
|
|
min-height: 60px; |
|
|
border: 2px dashed #cbd5e1; |
|
|
border-radius: 0.5rem; |
|
|
padding: 1rem; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
|
|
|
.dropzone-active { |
|
|
border-color: #2563eb; |
|
|
background-color: #eff6ff; |
|
|
} |
|
|
|
|
|
.print-only { |
|
|
display: none; |
|
|
} |
|
|
|
|
|
@media print { |
|
|
.no-print, .sidebar, .export-buttons { |
|
|
display: none !important; |
|
|
} |
|
|
|
|
|
.print-only { |
|
|
display: block !important; |
|
|
} |
|
|
|
|
|
.main-content { |
|
|
grid-template-columns: 1fr !important; |
|
|
} |
|
|
|
|
|
body { |
|
|
background: white !important; |
|
|
} |
|
|
|
|
|
.container { |
|
|
box-shadow: none !important; |
|
|
border-radius: 0 !important; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gradient-to-br from-gradient-start to-gradient-end min-h-screen"> |
|
|
<div class="container max-w-7xl mx-auto bg-white shadow-2xl rounded-2xl overflow-hidden"> |
|
|
|
|
|
<header class="bg-slate-800 text-white p-8 text-center"> |
|
|
<h1 class="text-3xl md:text-4xl font-bold mb-2 flex items-center justify-center gap-3"> |
|
|
<i class="fas fa-balance-scale"></i> |
|
|
Mapeamento de Argumentos - Processo Penal |
|
|
</h1> |
|
|
<p class="text-slate-300 text-sm md:text-base"> |
|
|
Ferramenta avançada para estruturação lógica de teses penais e processuais penais |
|
|
</p> |
|
|
</header> |
|
|
|
|
|
<div class="main-content grid md:grid-cols-12 gap-0 min-h-[calc(100vh-180px)]"> |
|
|
|
|
|
<div class="sidebar col-span-3 bg-slate-50 p-6 border-r border-slate-200 overflow-y-auto h-[calc(100vh-140px)]"> |
|
|
|
|
|
<div class="form-section mb-8"> |
|
|
<h3 class="text-lg font-semibold text-slate-700 mb-4 flex items-center gap-2"> |
|
|
<i class="fas fa-folder-open text-primary"></i> |
|
|
Informações do Caso |
|
|
</h3> |
|
|
|
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Tipo de Peça</label> |
|
|
<select id="tipoPeca" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm"> |
|
|
<option value="">Selecione...</option> |
|
|
<option value="denuncia">Denúncia</option> |
|
|
<option value="defesa">Defesa Prévia</option> |
|
|
<option value="alegacoes">Alegações Finais</option> |
|
|
<option value="recurso">Recurso</option> |
|
|
<option value="habeas">Habeas Corpus</option> |
|
|
<option value="parecer">Parecer</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Tipo Penal</label> |
|
|
<input type="text" id="tipoPenal" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: Art. 155, CP - Furto"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Réu/Investigado</label> |
|
|
<input type="text" id="reu" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Nome do réu"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Comarca/Tribunal</label> |
|
|
<input type="text" id="comarca" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: 1ª Vara Criminal de São Paulo"> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="form-section mb-8"> |
|
|
<h3 class="text-lg font-semibold text-slate-700 mb-4 flex items-center gap-2"> |
|
|
<i class="fas fa-flask text-primary"></i> |
|
|
Tese Central |
|
|
</h3> |
|
|
|
|
|
<div class="space-y-3"> |
|
|
<textarea id="teseCentral" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm min-h-24" placeholder="Digite a tese central que será defendida..."></textarea> |
|
|
<button onclick="adicionarTese()" class="w-full bg-primary hover:bg-blue-700 text-white font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-plus"></i> |
|
|
Atualizar Tese Central |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="form-section mb-8"> |
|
|
<h3 class="text-lg font-semibold text-slate-700 mb-4 flex items-center gap-2"> |
|
|
<i class="fas fa-book text-primary"></i> |
|
|
Adicionar Argumento |
|
|
</h3> |
|
|
|
|
|
<div class="space-y-3"> |
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Tipo de Argumento</label> |
|
|
<select id="tipoArgumento" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm"> |
|
|
<option value="normativo">Normativo</option> |
|
|
<option value="jurisprudencial">Jurisprudencial</option> |
|
|
<option value="doutrinario">Doutrinário</option> |
|
|
<option value="teleologico">Teleológico</option> |
|
|
<option value="sistematico">Sistemático</option> |
|
|
<option value="historico">Histórico</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Título</label> |
|
|
<input type="text" id="tituloArgumento" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: Princípio da Insignificância"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Fundamento</label> |
|
|
<textarea id="fundamentoArgumento" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm min-h-16" placeholder="Descreva o fundamento do argumento..."></textarea> |
|
|
</div> |
|
|
|
|
|
<button onclick="adicionarArgumento()" class="w-full bg-primary hover:bg-blue-700 text-white font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-plus"></i> |
|
|
Adicionar Argumento |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="form-section mb-8"> |
|
|
<h3 class="text-lg font-semibold text-slate-700 mb-4 flex items-center gap-2"> |
|
|
<i class="fas fa-exclamation-triangle text-primary"></i> |
|
|
Contra-Argumento |
|
|
</h3> |
|
|
|
|
|
<div class="space-y-3"> |
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Objeção</label> |
|
|
<textarea id="contraArgumento" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm min-h-16" placeholder="Digite o contra-argumento..."></textarea> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Refutação</label> |
|
|
<textarea id="refutacao" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm min-h-16" placeholder="Digite a refutação ao contra-argumento..."></textarea> |
|
|
</div> |
|
|
|
|
|
<button onclick="adicionarContraArgumento()" class="w-full bg-warning hover:bg-yellow-600 text-white font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-plus"></i> |
|
|
Adicionar Contra-Argumento |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="form-section mb-8"> |
|
|
<h3 class="text-lg font-semibold text-slate-700 mb-4 flex items-center gap-2"> |
|
|
<i class="fas fa-gavel text-primary"></i> |
|
|
Precedente |
|
|
</h3> |
|
|
|
|
|
<div class="space-y-3"> |
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Tribunal</label> |
|
|
<input type="text" id="tribunal" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: STF, STJ, TJSP"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Número do Processo</label> |
|
|
<input type="text" id="numeroProcesso" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: HC 123.456"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Relator</label> |
|
|
<input type="text" id="relator" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: Min. Gilmar Mendes"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Data</label> |
|
|
<input type="text" id="dataPrecedente" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Ex: 15/03/2024"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-xs font-semibold text-slate-600 mb-1">Ementa/Ratio Decidendi</label> |
|
|
<textarea id="ementa" class="w-full p-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent text-sm min-h-16" placeholder="Resumo da decisão..."></textarea> |
|
|
</div> |
|
|
|
|
|
<button onclick="adicionarPrecedente()" class="w-full bg-primary hover:bg-blue-700 text-white font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-plus"></i> |
|
|
Adicionar Precedente |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="export-buttons space-y-2"> |
|
|
<button onclick="exportarPDF()" class="w-full bg-info text-white hover:bg-cyan-600 font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-file-pdf"></i> |
|
|
Exportar PDF |
|
|
</button> |
|
|
|
|
|
<button onclick="exportarJSON()" class="w-full bg-success text-white hover:bg-green-600 font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-file-export"></i> |
|
|
Salvar JSON |
|
|
</button> |
|
|
|
|
|
<button onclick="importarJSON()" class="w-full bg-secondary text-white hover:bg-slate-600 font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-file-import"></i> |
|
|
Carregar JSON |
|
|
</button> |
|
|
|
|
|
<button onclick="limparTudo()" class="w-full bg-danger text-white hover:bg-red-700 font-semibold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> |
|
|
<i class="fas fa-trash"></i> |
|
|
Limpar Tudo |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="output-area col-span-9 p-8 bg-white overflow-y-auto h-[calc(100vh-140px)]"> |
|
|
<div id="outputArea" class="space-y-8"></div> |
|
|
|
|
|
<div class="print-only text-center mt-12 text-sm text-slate-500"> |
|
|
Documento gerado em: <span id="dataGeracao"></span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<input type="file" id="fileInput" class="hidden" accept=".json"> |
|
|
|
|
|
<script> |
|
|
let dados = { |
|
|
id: 1, |
|
|
tipoPeca: '', |
|
|
tipoPenal: '', |
|
|
reu: '', |
|
|
comarca: '', |
|
|
teseCentral: '', |
|
|
argumentos: [], |
|
|
contraArgumentos: [], |
|
|
precedentes: [] |
|
|
}; |
|
|
|
|
|
|
|
|
window.adicionarTese = function() { |
|
|
const tese = document.getElementById('teseCentral').value.trim(); |
|
|
if (!tese) { |
|
|
alert('Por favor, insira uma tese central.'); |
|
|
return; |
|
|
} |
|
|
|
|
|
dados.teseCentral = tese; |
|
|
dados.tipoPeca = document.getElementById('tipoPeca').value; |
|
|
dados.tipoPenal = document.getElementById('tipoPenal').value; |
|
|
dados.reu = document.getElementById('reu').value; |
|
|
dados.comarca = document.getElementById('comarca').value; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Tese central atualizada com sucesso!', 'success'); |
|
|
}; |
|
|
|
|
|
|
|
|
window.adicionarArgumento = function() { |
|
|
const tipo = document.getElementById('tipoArgumento').value; |
|
|
const titulo = document.getElementById('tituloArgumento').value.trim(); |
|
|
const fundamento = document.getElementById('fundamentoArgumento').value.trim(); |
|
|
|
|
|
if (!titulo || !fundamento) { |
|
|
showNotification('Preencha todos os campos do argumento', 'error'); |
|
|
return; |
|
|
} |
|
|
|
|
|
dados.argumentos.push({ |
|
|
id: Date.now(), |
|
|
tipo: tipo, |
|
|
titulo: titulo, |
|
|
fundamento: fundamento |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('tituloArgumento').value = ''; |
|
|
document.getElementById('fundamentoArgumento').value = ''; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Argumento adicionado com sucesso!', 'success'); |
|
|
}; |
|
|
|
|
|
|
|
|
window.adicionarContraArgumento = function() { |
|
|
const contra = document.getElementById('contraArgumento').value.trim(); |
|
|
const refutacao = document.getElementById('refutacao').value.trim(); |
|
|
|
|
|
if (!contra || !refutacao) { |
|
|
showNotification('Preencha tanto o contra-argumento quanto a refutação', 'error'); |
|
|
return; |
|
|
} |
|
|
|
|
|
dados.contraArgumentos.push({ |
|
|
id: Date.now(), |
|
|
contraArgumento: contra, |
|
|
refutacao: refutacao |
|
|
}); |
|
|
|
|
|
document.getElementById('contraArgumento').value = ''; |
|
|
document.getElementById('refutacao').value = ''; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Contra-argumento adicionado com sucesso!', 'success'); |
|
|
}; |
|
|
|
|
|
|
|
|
window.adicionarPrecedente = function() { |
|
|
const tribunal = document.getElementById('tribunal').value.trim(); |
|
|
const numero = document.getElementById('numeroProcesso').value.trim(); |
|
|
const ementa = document.getElementById('ementa').value.trim(); |
|
|
|
|
|
if (!tribunal || !numero || !ementa) { |
|
|
showNotification('Preencha pelo menos o tribunal, número do processo e ementa', 'error'); |
|
|
return; |
|
|
} |
|
|
|
|
|
dados.precedentes.push({ |
|
|
id: Date.now(), |
|
|
tribunal: tribunal, |
|
|
numero: numero, |
|
|
relator: document.getElementById('relator').value, |
|
|
data: document.getElementById('dataPrecedente').value, |
|
|
ementa: ementa |
|
|
}); |
|
|
|
|
|
document.getElementById('tribunal').value = ''; |
|
|
document.getElementById('numeroProcesso').value = ''; |
|
|
document.getElementById('relator').value = ''; |
|
|
document.getElementById('dataPrecedente').value = ''; |
|
|
document.getElementById('ementa').value = ''; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Precedente adicionado com sucesso!', 'success'); |
|
|
}; |
|
|
|
|
|
|
|
|
window.removerArgumento = function(id) { |
|
|
if (confirm('Tem certeza que deseja remover este argumento?')) { |
|
|
dados.argumentos = dados.argumentos.filter(arg => arg.id !== id); |
|
|
renderizar(); |
|
|
showNotification('Argumento removido com sucesso!', 'success'); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
window.removerContraArgumento = function(id) { |
|
|
if (confirm('Tem certeza que deseja remover este contra-argumento?')) { |
|
|
dados.contraArgumentos = dados.contraArgumentos.filter(contra => contra.id !== id); |
|
|
renderizar(); |
|
|
showNotification('Contra-argumento removido com sucesso!', 'success'); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
window.removerPrecedente = function(id) { |
|
|
if (confirm('Tem certeza que deseja remover este precedente?')) { |
|
|
dados.precedentes = dados.precedentes.filter(prec => prec.id !== id); |
|
|
renderizar(); |
|
|
showNotification('Precedente removido com sucesso!', 'success'); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
window.editarArgumento = function(id) { |
|
|
const argumento = dados.argumentos.find(arg => arg.id === id); |
|
|
if (!argumento) return; |
|
|
|
|
|
const novoTitulo = prompt('Editar título:', argumento.titulo); |
|
|
if (novoTitulo === null) return; |
|
|
|
|
|
const novaFundamentacao = prompt('Editar fundamentação:', argumento.fundamento); |
|
|
if (novaFundamentacao === null) return; |
|
|
|
|
|
argumento.titulo = novoTitulo; |
|
|
argumento.fundamento = novaFundamentacao; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Argumento atualizado com sucesso!', 'success'); |
|
|
}; |
|
|
|
|
|
|
|
|
window.exportarPDF = function() { |
|
|
|
|
|
document.getElementById('dataGeracao').textContent = new Date().toLocaleDateString('pt-BR'); |
|
|
|
|
|
|
|
|
window.print(); |
|
|
}; |
|
|
|
|
|
|
|
|
window.exportarJSON = function() { |
|
|
const dataStr = JSON.stringify(dados, null, 2); |
|
|
const dataBlob = new Blob([dataStr], {type: 'application/json'}); |
|
|
const url = URL.createObjectURL(dataBlob); |
|
|
const link = document.createElement('a'); |
|
|
link.href = url; |
|
|
link.download = `mapeamento_argumentos_${new Date().toISOString().split('T')[0]}.json`; |
|
|
link.click(); |
|
|
|
|
|
showNotification('Arquivo JSON salvo com sucesso!', 'success'); |
|
|
}; |
|
|
|
|
|
|
|
|
window.importarJSON = function() { |
|
|
document.getElementById('fileInput').click(); |
|
|
}; |
|
|
|
|
|
|
|
|
window.limparTudo = function() { |
|
|
if (confirm('Tem certeza que deseja limpar todos os dados? Esta ação não pode ser desfeita.')) { |
|
|
dados = { |
|
|
id: 1, |
|
|
tipoPeca: '', |
|
|
tipoPenal: '', |
|
|
reu: '', |
|
|
comarca: '', |
|
|
teseCentral: '', |
|
|
argumentos: [], |
|
|
contraArgumentos: [], |
|
|
precedentes: [] |
|
|
}; |
|
|
|
|
|
|
|
|
document.getElementById('tipoPeca').value = ''; |
|
|
document.getElementById('tipoPenal').value = ''; |
|
|
document.getElementById('reu').value = ''; |
|
|
document.getElementById('comarca').value = ''; |
|
|
document.getElementById('teseCentral').value = ''; |
|
|
document.getElementById('tituloArgumento').value = ''; |
|
|
document.getElementById('fundamentoArgumento').value = ''; |
|
|
document.getElementById('contraArgumento').value = ''; |
|
|
document.getElementById('refutacao').value = ''; |
|
|
document.getElementById('tribunal').value = ''; |
|
|
document.getElementById('numeroProcesso').value = ''; |
|
|
document.getElementById('relator').value = ''; |
|
|
document.getElementById('dataPrecedente').value = ''; |
|
|
document.getElementById('ementa').value = ''; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Todos os dados foram limpos com sucesso!', 'success'); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
function renderizar() { |
|
|
const output = document.getElementById('outputArea'); |
|
|
|
|
|
|
|
|
if (!dados.teseCentral && dados.argumentos.length === 0 && |
|
|
dados.contraArgumentos.length === 0 && dados.precedentes.length === 0) { |
|
|
output.innerHTML = ` |
|
|
<div class="flex flex-col items-center justify-center py-20 text-center space-y-4"> |
|
|
<i class="fas fa-folder-open text-slate-300 text-6xl"></i> |
|
|
<h3 class="text-xl font-semibold text-slate-500">Nenhum mapeamento criado</h3> |
|
|
<p class="text-slate-400 max-w-md">Preencha os campos ao lado para começar a estruturar seus argumentos jurídicos</p> |
|
|
<div class="flex flex-wrap justify-center gap-2 mt-4 text-xs text-slate-400"> |
|
|
<span class="bg-slate-100 px-3 py-1 rounded-full">Tese Central</span> |
|
|
<span class="bg-slate-100 px-3 py-1 rounded-full">Argumentos</span> |
|
|
<span class="bg-slate-100 px-3 py-1 rounded-full">Contra-argumentos</span> |
|
|
<span class="bg-slate-100 px-3 py-1 rounded-full">Precedentes</span> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
let html = ''; |
|
|
|
|
|
|
|
|
if (dados.tipoPeca || dados.tipoPenal || dados.reu || dados.comarca) { |
|
|
html += ` |
|
|
<div class="bg-slate-50 border-l-4 border-primary p-6 rounded-r-lg mb-8"> |
|
|
<h4 class="font-semibold text-slate-700 mb-3 flex items-center gap-2"> |
|
|
<i class="fas fa-folder-open text-primary"></i> |
|
|
INFORMAÇÕES DO CASO |
|
|
</h4> |
|
|
<div class="grid md:grid-cols-2 gap-3 text-sm"> |
|
|
`; |
|
|
|
|
|
if (dados.tipoPeca) { |
|
|
html += `<div><span class="font-medium">Tipo de Peça:</span> ${getNomePeca(dados.tipoPeca)}</div>`; |
|
|
} |
|
|
if (dados.tipoPenal) { |
|
|
html += `<div><span class="font-medium">Tipo Penal:</span> ${dados.tipoPenal}</div>`; |
|
|
} |
|
|
if (dados.reu) { |
|
|
html += `<div><span class="font-medium">Réu/Investigado:</span> ${dados.reu}</div>`; |
|
|
} |
|
|
if (dados.comarca) { |
|
|
html += `<div><span class="font-medium">Comarca/Tribunal:</span> ${dados.comarca}</div>`; |
|
|
} |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
|
|
|
if (dados.teseCentral) { |
|
|
html += ` |
|
|
<div class="bg-gradient-to-r from-danger to-red-600 text-white p-8 rounded-xl mb-8 card-hover fade-in"> |
|
|
<div class="flex items-start justify-between"> |
|
|
<div class="flex-1"> |
|
|
<h2 class="text-2xl font-bold mb-3 flex items-center gap-3"> |
|
|
<i class="fas fa-flask"></i> |
|
|
TESE CENTRAL |
|
|
</h2> |
|
|
<p class="text-lg leading-relaxed">${dados.teseCentral}</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
|
|
|
if (dados.argumentos.length > 0) { |
|
|
html += ` |
|
|
<div class="mb-8"> |
|
|
<h3 class="text-2xl font-bold text-slate-700 mb-6 flex items-center gap-3"> |
|
|
<i class="fas fa-book-reader text-primary"></i> |
|
|
ARGUMENTOS |
|
|
</h3> |
|
|
<div class="grid gap-4 md:grid-cols-2"> |
|
|
`; |
|
|
|
|
|
dados.argumentos.forEach(arg => { |
|
|
const badgeColor = getBadgeColor(arg.tipo); |
|
|
html += ` |
|
|
<div class="bg-white border border-slate-200 rounded-lg p-5 shadow-sm card-hover group hover:shadow-md fade-in"> |
|
|
<div class="flex justify-between items-start mb-3"> |
|
|
<span class="badge ${badgeColor} flex items-center gap-1"> |
|
|
<i class="fas ${getIconForTipo(arg.tipo)} text-xs"></i> |
|
|
${arg.tipo.toUpperCase()} |
|
|
</span> |
|
|
<div class="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity"> |
|
|
<button onclick="editarArgumento(${arg.id})" class="p-1 text-slate-500 hover:text-primary text-sm" title="Editar"> |
|
|
<i class="fas fa-edit"></i> |
|
|
</button> |
|
|
<button onclick="removerArgumento(${arg.id})" class="p-1 text-slate-500 hover:text-danger text-sm" title="Remover"> |
|
|
<i class="fas fa-trash"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<h4 class="font-semibold text-slate-700 mb-2">${arg.titulo}</h4> |
|
|
<p class="text-slate-600 text-sm leading-relaxed">${arg.fundamento}</p> |
|
|
</div> |
|
|
`; |
|
|
}); |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
|
|
|
if (dados.precedentes.length > 0) { |
|
|
html += ` |
|
|
<div class="mb-8"> |
|
|
<h3 class="text-2xl font-bold text-slate-700 mb-6 flex items-center gap-3"> |
|
|
<i class="fas fa-gavel text-primary"></i> |
|
|
PRECEDENTES JURISPRUDENCIAIS |
|
|
</h3> |
|
|
<div class="bg-white rounded-lg shadow overflow-hidden"> |
|
|
<table class="min-w-full divide-y divide-slate-200"> |
|
|
<thead class="bg-slate-50"> |
|
|
<tr> |
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Tribunal / Processo</th> |
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Relator / Data</th> |
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Decisão</th> |
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Ações</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody class="bg-white divide-y divide-slate-200"> |
|
|
`; |
|
|
|
|
|
dados.precedentes.forEach(prec => { |
|
|
html += ` |
|
|
<tr class="hover:bg-slate-50 transition-colors"> |
|
|
<td class="px-6 py-4"> |
|
|
<div class="font-semibold text-slate-700">${prec.tribunal}</div> |
|
|
<div class="text-sm text-slate-500">${prec.numero}</div> |
|
|
</td> |
|
|
<td class="px-6 py-4"> |
|
|
<div class="text-slate-700">${prec.relator}</div> |
|
|
<div class="text-sm text-slate-500">${prec.data}</div> |
|
|
</td> |
|
|
<td class="px-6 py-4 text-sm text-slate-600">${prec.ementa}</td> |
|
|
<td class="px-6 py-4 whitespace-nowrap"> |
|
|
<button onclick="removerPrecedente(${prec.id})" class="text-danger hover:text-red-700 transition-colors"> |
|
|
<i class="fas fa-trash"></i> |
|
|
</button> |
|
|
</td> |
|
|
</tr> |
|
|
`; |
|
|
}); |
|
|
|
|
|
html += ` |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
|
|
|
if (dados.contraArgumentos.length > 0) { |
|
|
html += ` |
|
|
<div class="mb-8"> |
|
|
<h3 class="text-2xl font-bold text-slate-700 mb-6 flex items-center gap-3"> |
|
|
<i class="fas fa-balance-scale-right text-primary"></i> |
|
|
CONTRA-ARGUMENTOS E REFUTAÇÕES |
|
|
</h3> |
|
|
<div class="space-y-6"> |
|
|
`; |
|
|
|
|
|
dados.contraArgumentos.forEach(contra => { |
|
|
html += ` |
|
|
<!-- Contra-argumento --> |
|
|
<div class="bg-amber-50 border-l-4 border-amber-500 p-5 rounded-r-lg"> |
|
|
<div class="flex justify-between items-start mb-2"> |
|
|
<h4 class="font-semibold text-amber-800 flex items-center gap-2"> |
|
|
<i class="fas fa-exclamation-triangle"></i> |
|
|
CONTRA-ARGUMENTO |
|
|
</h4> |
|
|
<button onclick="removerContraArgumento(${contra.id})" class="text-amber-500 hover:text-amber-700"> |
|
|
<i class="fas fa-trash"></i> |
|
|
</button> |
|
|
</div> |
|
|
<p class="text-amber-700">${contra.contraArgumento}</p> |
|
|
</div> |
|
|
|
|
|
<!-- Refutação --> |
|
|
<div class="bg-emerald-50 border-l-4 border-emerald-500 p-5 rounded-r-lg"> |
|
|
<h4 class="font-semibold text-emerald-800 flex items-center gap-2 mb-2"> |
|
|
<i class="fas fa-check-circle"></i> |
|
|
REFUTAÇÃO |
|
|
</h4> |
|
|
<p class="text-emerald-700">${contra.refutacao}</p> |
|
|
</div> |
|
|
`; |
|
|
}); |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
|
|
|
const argumentosNormativos = dados.argumentos.filter(a => a.tipo === 'normativo'); |
|
|
if (argumentosNormativos.length > 0 && dados.teseCentral) { |
|
|
html += ` |
|
|
<div class="mb-8"> |
|
|
<h3 class="text-2xl font-bold text-slate-700 mb-6 flex items-center gap-3"> |
|
|
<i class="fas fa-atom text-primary"></i> |
|
|
SILOGISMO JURÍDICO |
|
|
</h3> |
|
|
<div class="bg-slate-50 rounded-xl p-6 border border-slate-200"> |
|
|
<div class="grid md:grid-cols-12 gap-4"> |
|
|
`; |
|
|
|
|
|
|
|
|
html += ` |
|
|
<div class="md:col-span-4"> |
|
|
<div class="bg-white border-l-4 border-blue-500 p-4 rounded-lg h-full"> |
|
|
<h4 class="font-bold text-blue-700 mb-3 flex items-center gap-2"> |
|
|
<i class="fas fa-cube"></i> |
|
|
PREMISSA MAIOR |
|
|
<div class="ml-auto text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded"> |
|
|
Norma |
|
|
</div> |
|
|
</h4> |
|
|
`; |
|
|
|
|
|
argumentosNormativos.forEach(arg => { |
|
|
html += `<p class="text-sm mb-2 text-blue-700"><strong>${arg.titulo}:</strong> ${arg.fundamento}</p>`; |
|
|
}); |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
|
|
|
html += ` |
|
|
<div class="md:col-span-4 flex items-center justify-center"> |
|
|
<div class="text-4xl text-slate-400"> |
|
|
<i class="fas fa-arrow-right"></i> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="md:col-span-4"> |
|
|
<div class="bg-white border-l-4 border-green-500 p-4 rounded-lg h-full"> |
|
|
<h4 class="font-bold text-green-700 mb-3 flex items-center gap-2"> |
|
|
<i class="fas fa-file-contract"></i> |
|
|
PREMISSA MENOR |
|
|
<div class="ml-auto text-xs bg-green-100 text-green-700 px-2 py-1 rounded"> |
|
|
Fato |
|
|
</div> |
|
|
</h4> |
|
|
<p class="text-sm text-green-700">Aplicável ao caso concreto conforme a tese apresentada</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="md:col-span-12 flex items-center justify-center mt-4"> |
|
|
<div class="text-4xl text-slate-400"> |
|
|
<i class="fas fa-long-arrow-alt-down"></i> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="md:col-span-12"> |
|
|
<div class="bg-white border-l-4 border-purple-500 p-5 rounded-lg"> |
|
|
<h4 class="font-bold text-purple-700 mb-3 flex items-center gap-2"> |
|
|
<i class="fas fa-lightbulb"></i> |
|
|
CONCLUSÃO |
|
|
<div class="ml-auto text-xs bg-purple-100 text-purple-700 px-2 py-1 rounded"> |
|
|
Resultado |
|
|
</div> |
|
|
</h4> |
|
|
<p class="text-lg font-semibold text-purple-700">${dados.teseCentral}</p> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
|
|
|
if (dados.argumentos.length > 0) { |
|
|
html += ` |
|
|
<div class="mb-8"> |
|
|
<h3 class="text-2xl font-bold text-slate-700 mb-6 flex items-center gap-3"> |
|
|
<i class="fas fa-sitemap text-primary"></i> |
|
|
MAPA DE ARGUMENTOS |
|
|
</h3> |
|
|
<div class="bg-white rounded-xl p-6 border border-slate-200 relative"> |
|
|
<div class="timeline ml-7 space-y-12"> |
|
|
`; |
|
|
|
|
|
|
|
|
const tipos = ['normativo', 'jurisprudencial', 'doutrinario', 'teleologico', 'sistematico', 'historico']; |
|
|
const nomesTipos = { |
|
|
'normativo': 'Normativo', |
|
|
'jurisprudencial': 'Jurisprudencial', |
|
|
'doutrinario': 'Doutrinário', |
|
|
'teleologico': 'Teleológico', |
|
|
'sistematico': 'Sistemático', |
|
|
'historico': 'Histórico' |
|
|
}; |
|
|
|
|
|
tipos.forEach(tipo => { |
|
|
const argsDoTipo = dados.argumentos.filter(arg => arg.tipo === tipo); |
|
|
if (argsDoTipo.length > 0) { |
|
|
html += ` |
|
|
<div class="timeline-item ml-6"> |
|
|
<div class="bg-white border-2 border-${getBadgeColor(tipo).split('-')[1]} rounded-lg p-4 hover:shadow-md transition-shadow"> |
|
|
<h4 class="font-bold text-${getBadgeColor(tipo).split('-')[1]}-700 flex items-center gap-2 mb-3"> |
|
|
<i class="fas ${getIconForTipo(tipo)}"></i> |
|
|
${nomesTipos[tipo]} (${argsDoTipo.length}) |
|
|
</h4> |
|
|
<div class="space-y-2"> |
|
|
`; |
|
|
|
|
|
argsDoTipo.forEach(arg => { |
|
|
html += `<div class="text-sm text-slate-700 flex items-start gap-2"><i class="fas fa-dot-circle text-${getBadgeColor(tipo).split('-')[1]} text-xs mt-1.5"></i> ${arg.titulo}</div>`; |
|
|
}); |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
}); |
|
|
|
|
|
html += ` |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
output.innerHTML = html; |
|
|
} |
|
|
|
|
|
|
|
|
function getNomePeca(tipo) { |
|
|
const nomes = { |
|
|
'denuncia': 'Denúncia', |
|
|
'defesa': 'Defesa Prévia', |
|
|
'alegacoes': 'Alegações Finais', |
|
|
'recurso': 'Recurso', |
|
|
'habeas': 'Habeas Corpus', |
|
|
'parecer': 'Parecer' |
|
|
}; |
|
|
return nomes[tipo] || tipo; |
|
|
} |
|
|
|
|
|
|
|
|
function getBadgeColor(tipo) { |
|
|
const cores = { |
|
|
'normativo': 'bg-blue-100 text-blue-800 border border-blue-200', |
|
|
'jurisprudencial': 'bg-cyan-100 text-cyan-800 border border-cyan-200', |
|
|
'doutrinario': 'bg-purple-100 text-purple-800 border border-purple-200', |
|
|
'teleologico': 'bg-amber-100 text-amber-800 border border-amber-200', |
|
|
'sistematico': 'bg-pink-100 text-pink-800 border border-pink-200', |
|
|
'historico': 'bg-teal-100 text-teal-800 border border-teal-200' |
|
|
}; |
|
|
return cores[tipo] || 'bg-gray-100 text-gray-800'; |
|
|
} |
|
|
|
|
|
|
|
|
function getIconForTipo(tipo) { |
|
|
const icones = { |
|
|
'normativo': 'fa-balance-scale', |
|
|
'jurisprudencial': 'fa-gavel', |
|
|
'doutrinario': 'fa-book', |
|
|
'teleologico': 'fa-bullseye', |
|
|
'sistematico': 'fa-project-diagram', |
|
|
'historico': 'fa-hourglass-half' |
|
|
}; |
|
|
return icones[tipo] || 'fa-question'; |
|
|
} |
|
|
|
|
|
|
|
|
function showNotification(message, type = 'info') { |
|
|
|
|
|
const notification = document.createElement('div'); |
|
|
notification.className = `fixed top-4 right-4 z-50 max-w-md rounded-lg shadow-lg px-4 py-3 text-white font-medium animate-fade-in-out transform transition-all duration-300 ${getNotificationColor(type)}`; |
|
|
notification.style.transform = 'translateY(0px)'; |
|
|
notification.innerHTML = ` |
|
|
<div class="flex items-center justify-between"> |
|
|
<div class="flex items-center gap-3"> |
|
|
<i class="${getNotificationIcon(type)}"></i> |
|
|
<span>${message}</span> |
|
|
</div> |
|
|
<button onclick="this.parentElement.parentElement.remove()" class="text-white opacity-70 hover:opacity-100"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
document.body.appendChild(notification); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
notification.style.transform = 'translateY(-100px)'; |
|
|
setTimeout(() => { |
|
|
notification.remove(); |
|
|
}, 300); |
|
|
}, 5000); |
|
|
} |
|
|
|
|
|
|
|
|
function getNotificationColor(type) { |
|
|
const colors = { |
|
|
'success': 'bg-green-500', |
|
|
'error': 'bg-red-500', |
|
|
'info': 'bg-blue-500', |
|
|
'warning': 'bg-amber-500' |
|
|
}; |
|
|
return colors[type] || 'bg-blue-500'; |
|
|
} |
|
|
|
|
|
|
|
|
function getNotificationIcon(type) { |
|
|
const icons = { |
|
|
'success': 'fas fa-check-circle', |
|
|
'error': 'fas fa-exclamation-circle', |
|
|
'info': 'fas fa-info-circle', |
|
|
'warning': 'fas fa-exclamation-triangle' |
|
|
}; |
|
|
return icons[type] || 'fas fa-info-circle'; |
|
|
} |
|
|
|
|
|
|
|
|
document.getElementById('fileInput').addEventListener('change', function(e) { |
|
|
const file = e.target.files[0]; |
|
|
if (!file) return; |
|
|
|
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(e) { |
|
|
try { |
|
|
const dadosImportados = JSON.parse(e.target.result); |
|
|
|
|
|
|
|
|
if (!dadosImportados.hasOwnProperty('teseCentral')) { |
|
|
throw new Error('Arquivo com formato inválido'); |
|
|
} |
|
|
|
|
|
dados = dadosImportados; |
|
|
|
|
|
|
|
|
document.getElementById('tipoPeca').value = dados.tipoPeca || ''; |
|
|
document.getElementById('tipoPenal').value = dados.tipoPenal || ''; |
|
|
document.getElementById('reu').value = dados.reu || ''; |
|
|
document.getElementById('comarca').value = dados.comarca || ''; |
|
|
document.getElementById('teseCentral').value = dados.teseCentral || ''; |
|
|
|
|
|
renderizar(); |
|
|
showNotification('Mapeamento carregado com sucesso!', 'success'); |
|
|
} catch (error) { |
|
|
console.error(error); |
|
|
showNotification('Erro ao carregar arquivo. Verifique se é um JSON válido.', 'error'); |
|
|
} |
|
|
}; |
|
|
reader.readAsText(file); |
|
|
}); |
|
|
|
|
|
|
|
|
renderizar(); |
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-qwensite.hf.space/logo.svg" alt="qwensite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-qwensite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >QwenSite</a> - 🧬 <a href="https://enzostvs-qwensite.hf.space?remix=alexandremoraisdarosa/mapeamento-argumentos" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
|
</html> |