mapeamento-argumentos / index.html
alexandremoraisdarosa's picture
Add 3 files
381e428 verified
<!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">
<!-- Cabeçalho -->
<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)]">
<!-- Sidebar -->
<div class="sidebar col-span-3 bg-slate-50 p-6 border-r border-slate-200 overflow-y-auto h-[calc(100vh-140px)]">
<!-- Informações do Caso -->
<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>
<!-- Tese Central -->
<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>
<!-- Adicionar Argumento -->
<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>
<!-- Contra-Argumento -->
<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>
<!-- Precedente -->
<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>
<!-- Exportar/Importar -->
<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>
<!-- Área de Saída -->
<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>
<!-- Para importação de JSON -->
<input type="file" id="fileInput" class="hidden" accept=".json">
<script>
let dados = {
id: 1,
tipoPeca: '',
tipoPenal: '',
reu: '',
comarca: '',
teseCentral: '',
argumentos: [],
contraArgumentos: [],
precedentes: []
};
// Adicionar Tese Central
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');
};
// Adicionar Argumento
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
});
// Limpar formulário
document.getElementById('tituloArgumento').value = '';
document.getElementById('fundamentoArgumento').value = '';
renderizar();
showNotification('Argumento adicionado com sucesso!', 'success');
};
// Adicionar Contra-Argumento
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');
};
// Adicionar Precedente
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');
};
// Remover Argumento
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');
}
};
// Remover Contra-Argumento
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');
}
};
// Remover Precedente
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');
}
};
// Editar Argumento
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');
};
// Exportar PDF
window.exportarPDF = function() {
// Atualizar data de geração
document.getElementById('dataGeracao').textContent = new Date().toLocaleDateString('pt-BR');
// Imprimir
window.print();
};
// Exportar JSON
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');
};
// Importar JSON
window.importarJSON = function() {
document.getElementById('fileInput').click();
};
// Limpar Tudo
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: []
};
// Limpar todos os campos do formulário
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');
}
};
// Função para renderizar o conteúdo
function renderizar() {
const output = document.getElementById('outputArea');
// Se não houver dados, mostrar estado vazio
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;
}
// Montar o conteúdo
let html = '';
// Informações do caso
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>
`;
}
// Tese Central
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>
`;
}
// Argumentos
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>
`;
}
// Precedentes
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>
`;
}
// Contra-argumentos e Refutações
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>
`;
}
// Silogismo Jurídico
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">
`;
// Premissa Maior
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>
`;
// Premissa Menor
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>
`;
}
// Mapa de Argumentos
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">
`;
// Agrupar argumentos por tipo
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;
}
// Função para obter o nome da peça
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;
}
// Função para obter a cor do badge
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';
}
// Função para obter o ícone para o tipo de argumento
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';
}
// Função para exibir notificações
function showNotification(message, type = 'info') {
// Criar elemento de notificação
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);
// Remover automaticamente após 5 segundos
setTimeout(() => {
notification.style.transform = 'translateY(-100px)';
setTimeout(() => {
notification.remove();
}, 300);
}, 5000);
}
// Função para obter a cor da notificação
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';
}
// Função para obter o ícone da notificação
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';
}
// Event listener para importação de JSON
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);
// Validar estrutura básica
if (!dadosImportados.hasOwnProperty('teseCentral')) {
throw new Error('Arquivo com formato inválido');
}
dados = dadosImportados;
// Preencher campos do formulário
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 inicialmente
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>