Em português. Crie e implemente as dependências. Armazenamento local. Gere instruções de uso. <!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Análise de Derrotabilidade - Casos Penais</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.jsdelivr.net/npm/lucide@latest/dist/umd/lucide.js"></script> <style> .evidence-row:nth-child(even) { background-color: #f8fafc; } .conclusion-defeated { background-color: #fef2f2; border-left: 4px solid #ef4444; } .conclusion-active { background-color: #f0fdf4; border-left: 4px solid #22c55e; } .conclusion-review { background-color: #fefce8; border-left: 4px solid #eab308; } .fade-in { animation: fadeIn 0.5s ease-in; }
@keyframes
fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .btn-primary {
@apply
bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors; } .btn-secondary {
@apply
bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition-colors; } .btn-success {
@apply
bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition-colors; } .btn-danger {
@apply
bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors; } .form-input {
@apply
w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent; } .form-textarea {
@apply
w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-vertical; } .status-badge {
@apply
px-3 py-1 rounded-full text-sm font-medium; } .status-defeated {
@apply
bg-red-100 text-red-800; } .status-active {
@apply
bg-green-100 text-green-800; } .status-review {
@apply
bg-yellow-100 text-yellow-800; } .print-hidden {
@media
print { display: none !important; } }
@media
print { body { font-size: 12px; } .container { max-width: none; margin: 0; padding: 10px; } .shadow-lg { box-shadow: none; } } </style> </head> <body class="bg-gray-50 min-h-screen"> <!-- Header --> <header class="bg-white shadow-sm border-b print-hidden"> <div class="max-w-7xl mx-auto px-4 py-4"> <div class="flex justify-between items-center"> <div> <h1 class="text-2xl font-bold text-gray-900">Análise de Derrotabilidade</h1> <p class="text-gray-600">Sistema de Acompanhamento de Casos Penais</p> </div> <div class="flex space-x-2"> <button onclick="exportToPDF()" class="btn-secondary"> <i data-lucide="download" class="w-4 h-4 inline mr-2"></i>Exportar PDF </button> <button onclick="printCase()" class="btn-primary"> <i data-lucide="printer" class="w-4 h-4 inline mr-2"></i>Imprimir </button> </div> </div> </div> </header> <div class="max-w-7xl mx-auto px-4 py-6"> <!-- Case Information Form --> <div class="bg-white rounded-lg shadow-lg p-6 mb-6"> <h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center"> <i data-lucide="folder" class="w-5 h-5 mr-2"></i>Informações do Caso </h2> <div class="grid md:grid-cols-2 gap-4"> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Número do Processo</label> <input type="text" id="caseNumber" class="form-input" placeholder="Ex: 0001234-56.2024.8.01.0001"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Data de Abertura</label> <input type="date" id="caseDate" class="form-input"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Delegado Responsável</label> <input type="text" id="investigator" class="form-input" placeholder="Nome do delegado"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Tipo de Crime</label> <select id="crimeType" class="form-input"> <option value="">Selecione o tipo</option> <option value="homicidio">Homicídio</option> <option value="furto">Furto</option> <option value="roubo">Roubo</option> <option value="estelionato">Estelionato</option> <option value="trafico">Tráfico de Drogas</option> <option value="outros">Outros</option> </select> </div> <div class="md:col-span-2"> <label class="block text-sm font-medium text-gray-700 mb-2">Descrição do Caso</label> <textarea id="caseDescription" rows="3" class="form-textarea" placeholder="Breve descrição dos fatos..."></textarea> </div> </div> </div> <!-- Add New Phase Form --> <div class="bg-white rounded-lg shadow-lg p-6 mb-6 print-hidden"> <h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center"> <i data-lucide="plus-circle" class="w-5 h-5 mr-2"></i>Adicionar Nova Fase Investigativa </h2> <div class="grid md:grid-cols-2 gap-4"> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Nome da Fase</label> <input type="text" id="phaseName" class="form-input" placeholder="Ex: Investigação Inicial"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Período</label> <input type="text" id="phasePeriod" class="form-input" placeholder="Ex: Semana 1"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Principal Suspeito</label> <input type="text" id="suspect" class="form-input" placeholder="Nome do suspeito"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Status da Conclusão</label> <select id="conclusionStatus" class="form-input"> <option value="active">Ativa</option> <option value="defeated">Derrotada</option> <option value="review">Em Revisão</option> </select> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Evidências (uma por linha)</label> <textarea id="evidence" rows="4" class="form-textarea" placeholder="Lista as evidências encontradas..."></textarea> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Motivo/Justificativa</label> <textarea id="justification" rows="4" class="form-textarea" placeholder="Explique o motivo da conclusão..."></textarea> </div> </div> <div class="mt-4 flex justify-end"> <button onclick="addPhase()" class="btn-success"> <i data-lucide="plus" class="w-4 h-4 inline mr-2"></i>Adicionar Fase </button> </div> </div> <!-- Investigation Timeline Table --> <div class="bg-white rounded-lg shadow-lg overflow-hidden"> <div class="px-6 py-4 bg-gray-800 text-white"> <h2 class="text-xl font-bold flex items-center"> <i data-lucide="timeline" class="w-5 h-5 mr-2"></i>Linha do Tempo da Investigação </h2> </div> <div class="overflow-x-auto"> <table class="w-full" id="investigationTable"> <thead class="bg-gray-100"> <tr> <th class="px-4 py-3 text-left font-semibold text-gray-700">Fase</th> <th class="px-4 py-3 text-left font-semibold text-gray-700">Período</th> <th class="px-4 py-3 text-left font-semibold text-gray-700">Evidências Disponíveis</th> <th class="px-4 py-3 text-left font-semibold text-gray-700">Principal Suspeito</th> <th class="px-4 py-3 text-left font-semibold text-gray-700">Motivo/Justificativa</th> <th class="px-4 py-3 text-left font-semibold text-gray-700">Status da Conclusão</th> <th class="px-4 py-3 text-left font-semibold text-gray-700 print-hidden">Ações</th> </tr> </thead> <tbody id="investigationTableBody"> <!-- Rows will be added dynamically --> </tbody> </table> </div> <div id="emptyState" class="p-8 text-center text-gray-500"> <i data-lucide="search" class="w-12 h-12 mx-auto mb-4 text-gray-300"></i> <p>Nenhuma fase investigativa adicionada ainda.</p> <p class="text-sm">Use o formulário acima para começar a documentar o caso.</p> </div> </div> <!-- Principles Section --> <div class="mt-8 bg-white rounded-lg shadow-lg p-6"> <h2 class="text-2xl font-bold mb-4 text-gray-800 flex items-center"> <i data-lucide="book-open" class="w-6 h-6 mr-2"></i>Princípios da Derrotabilidade Aplicados </h2> <div class="grid md:grid-cols-2 gap-6"> <div class="space-y-4"> <div class="flex items-start space-x-3"> <div class="w-3 h-3 bg-blue-500 rounded-full mt-1.5 flex-shrink-0"></div> <div> <h3 class="font-semibold text-gray-800">Conclusões Racionais mas Revisíveis</h3> <p class="text-sm text-gray-600">Cada hipótese deve ser lógica baseada nas evidências disponíveis no momento, mas sempre passível de revisão.</p> </div> </div> <div class="flex items-start space-x-3"> <div class="w-3 h-3 bg-green-500 rounded-full mt-1.5 flex-shrink-0"></div> <div> <h3 class="font-semibold text-gray-800">Não Monotonia</h3> <p class="text-sm text-gray-600">Novas evidências podem alterar completamente as conclusões anteriores, invalidando hipóteses previamente aceitas.</p> </div> </div> </div> <div class="space-y-4"> <div class="flex items-start space-x-3"> <div class="w-3 h-3 bg-yellow-500 rounded-full mt-1.5 flex-shrink-0"></div> <div> <h3 class="font-semibold text-gray-800">Contexto Dinâmico</h3> <p class="text-sm text-gray-600">A investigação deve evoluir conforme novas informações emergem, mantendo flexibilidade analítica.</p> </div> </div> <div class="flex items-start space-x-3"> <div class="w-3 h-3 bg-red-500 rounded-full mt-1.5 flex-shrink-0"></div> <div> <h3 class="font-semibold text-gray-800">Proteção contra Erros</h3> <p class="text-sm text-gray-600">A análise contínua e revisão sistemática previnem conclusões precipitadas e injustiças.</p> </div> </div> </div> </div> </div> <!-- Summary Statistics --> <div class="mt-8 bg-white rounded-lg shadow-lg p-6"> <h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center"> <i data-lucide="bar-chart-3" class="w-5 h-5 mr-2"></i>Resumo Estatístico </h2> <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> <div class="text-center p-4 bg-blue-50 rounded-lg"> <div class="text-2xl font-bold text-blue-600" id="totalPhases">0</div> <div class="text-sm text-gray-600">Total de Fases</div> </div> <div class="text-center p-4 bg-green-50 rounded-lg"> <div class="text-2xl font-bold text-green-600" id="activeConclusions">0</div> <div class="text-sm text-gray-600">Conclusões Ativas</div> </div> <div class="text-center p-4 bg-red-50 rounded-lg"> <div class="text-2xl font-bold text-red-600" id="defeatedConclusions">0</div> <div class="text-sm text-gray-600">Conclusões Derrotadas</div> </div> <div class="text-center p-4 bg-yellow-50 rounded-lg"> <div class="text-2xl font-bold text-yellow-600" id="reviewConclusions">0</div> <div class="text-sm text-gray-600">Em Revisão</div> </div> </div> </div> </div> <script> // Initialize Lucide icons lucide.createIcons(); let phases = []; let phaseCounter = 0; // Set current date as default document.getElementById('caseDate').value = new Date().toISOString().split('T')[0]; function addPhase() { const phaseName = document.getElementById('phaseName').value.trim(); const phasePeriod = document.getElementById('phasePeriod').value.trim(); const suspect = document.getElementById('suspect').value.trim(); const evidence = document.getElementById('evidence').value.trim(); const justification = document.getElementById('justification').value.trim(); const status = document.getElementById('conclusionStatus').value; if (!phaseName || !phasePeriod || !suspect || !evidence || !justification) { alert('Por favor, preencha todos os campos obrigatórios.'); return; } const phase = { id: ++phaseCounter, name: phaseName, period: phasePeriod, suspect: suspect, evidence: evidence.split('\n').filter(e => e.trim()), justification: justification, status: status, timestamp: new Date().toLocaleString('pt-BR') }; phases.push(phase); renderTable(); updateStatistics(); clearForm(); } function clearForm() { document.getElementById('phaseName').value = ''; document.getElementById('phasePeriod').value = ''; document.getElementById('suspect').value = ''; document.getElementById('evidence').value = ''; document.getElementById('justification').value = ''; document.getElementById('conclusionStatus').value = 'active'; } function renderTable() { const tbody = document.getElementById('investigationTableBody'); const emptyState = document.getElementById('emptyState'); if (phases.length === 0) { tbody.innerHTML = ''; emptyState.style.display = 'block'; return; } emptyState.style.display = 'none'; tbody.innerHTML = phases.map - Initial Deployment
7a42648
verified
<html lang="pt-BR"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Análise de Derrotabilidade - Casos Penais</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script src="https://cdn.jsdelivr.net/npm/lucide@latest/dist/umd/lucide.js"></script> | |
<style> | |
.evidence-row:nth-child(even) { background-color: #f8fafc; } | |
.conclusion-defeated { background-color: #fef2f2; border-left: 4px solid #ef4444; } | |
.conclusion-active { background-color: #f0fdf4; border-left: 4px solid #22c55e; } | |
.conclusion-review { background-color: #fefce8; border-left: 4px solid #eab308; } | |
.fade-in { animation: fadeIn 0.5s ease-in; } | |
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } | |
.btn-primary { @apply bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors; } | |
.btn-secondary { @apply bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition-colors; } | |
.btn-success { @apply bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition-colors; } | |
.btn-danger { @apply bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors; } | |
.form-input { @apply w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent; } | |
.form-textarea { @apply w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-vertical; } | |
.status-badge { @apply px-3 py-1 rounded-full text-sm font-medium; } | |
.status-defeated { @apply bg-red-100 text-red-800; } | |
.status-active { @apply bg-green-100 text-green-800; } | |
.status-review { @apply bg-yellow-100 text-yellow-800; } | |
.print-hidden { @media print { display: none ; } } | |
@media print { | |
body { font-size: 12px; } | |
.container { max-width: none; margin: 0; padding: 10px; } | |
.shadow-lg { box-shadow: none; } | |
} | |
</style> | |
</head> | |
<body class="bg-gray-50 min-h-screen"> | |
<!-- Header --> | |
<header class="bg-white shadow-sm border-b print-hidden"> | |
<div class="max-w-7xl mx-auto px-4 py-4"> | |
<div class="flex justify-between items-center"> | |
<div> | |
<h1 class="text-2xl font-bold text-gray-900">Análise de Derrotabilidade</h1> | |
<p class="text-gray-600">Sistema de Acompanhamento de Casos Penais</p> | |
</div> | |
<div class="flex space-x-2"> | |
<button onclick="exportToPDF()" class="btn-secondary"> | |
<i data-lucide="download" class="w-4 h-4 inline mr-2"></i>Exportar PDF | |
</button> | |
<button onclick="printCase()" class="btn-primary"> | |
<i data-lucide="printer" class="w-4 h-4 inline mr-2"></i>Imprimir | |
</button> | |
</div> | |
</div> | |
</div> | |
</header> | |
<div class="max-w-7xl mx-auto px-4 py-6"> | |
<!-- Case Information Form --> | |
<div class="bg-white rounded-lg shadow-lg p-6 mb-6"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center"> | |
<i data-lucide="folder" class="w-5 h-5 mr-2"></i>Informações do Caso | |
</h2> | |
<div class="grid md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Número do Processo</label> | |
<input type="text" id="caseNumber" class="form-input" placeholder="Ex: 0001234-56.2024.8.01.0001"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Data de Abertura</label> | |
<input type="date" id="caseDate" class="form-input"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Delegado Responsável</label> | |
<input type="text" id="investigator" class="form-input" placeholder="Nome do delegado"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Tipo de Crime</label> | |
<select id="crimeType" class="form-input"> | |
<option value="">Selecione o tipo</option> | |
<option value="homicidio">Homicídio</option> | |
<option value="furto">Furto</option> | |
<option value="roubo">Roubo</option> | |
<option value="estelionato">Estelionato</option> | |
<option value="trafico">Tráfico de Drogas</option> | |
<option value="outros">Outros</option> | |
</select> | |
</div> | |
<div class="md:col-span-2"> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Descrição do Caso</label> | |
<textarea id="caseDescription" rows="3" class="form-textarea" placeholder="Breve descrição dos fatos..."></textarea> | |
</div> | |
<div class="md:col-span-2 flex justify-end space-x-2"> | |
<button onclick="saveCaseInfo()" class="btn-success"> | |
<i data-lucide="save" class="w-4 h-4 inline mr-2"></i>Salvar Informações | |
</button> | |
<button onclick="clearCaseInfo()" class="btn-secondary"> | |
<i data-lucide="trash-2" class="w-4 h-4 inline mr-2"></i>Limpar | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Add New Phase Form --> | |
<div class="bg-white rounded-lg shadow-lg p-6 mb-6 print-hidden"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center"> | |
<i data-lucide="plus-circle" class="w-5 h-5 mr-2"></i>Adicionar Nova Fase Investigativa | |
</h2> | |
<div class="grid md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Nome da Fase</label> | |
<input type="text" id="phaseName" class="form-input" placeholder="Ex: Investigação Inicial"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Período</label> | |
<input type="text" id="phasePeriod" class="form-input" placeholder="Ex: Semana 1"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Principal Suspeito</label> | |
<input type="text" id="suspect" class="form-input" placeholder="Nome do suspeito"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Status da Conclusão</label> | |
<select id="conclusionStatus" class="form-input"> | |
<option value="active">Ativa</option> | |
<option value="defeated">Derrotada</option> | |
<option value="review">Em Revisão</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Evidências (uma por linha)</label> | |
<textarea id="evidence" rows="4" class="form-textarea" placeholder="Lista as evidências encontradas..."></textarea> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Motivo/Justificativa</label> | |
<textarea id="justification" rows="4" class="form-textarea" placeholder="Explique o motivo da conclusão..."></textarea> | |
</div> | |
</div> | |
<div class="mt-4 flex justify-end space-x-2"> | |
<button onclick="clearPhaseForm()" class="btn-secondary"> | |
<i data-lucide="x" class="w-4 h-4 inline mr-2"></i>Limpar | |
</button> | |
<button onclick="addPhase()" class="btn-success"> | |
<i data-lucide="plus" class="w-4 h-4 inline mr-2"></i>Adicionar Fase | |
</button> | |
</div> | |
</div> | |
<!-- Investigation Timeline Table --> | |
<div class="bg-white rounded-lg shadow-lg overflow-hidden"> | |
<div class="px-6 py-4 bg-gray-800 text-white"> | |
<h2 class="text-xl font-bold flex items-center"> | |
<i data-lucide="timeline" class="w-5 h-5 mr-2"></i>Linha do Tempo da Investigação | |
</h2> | |
</div> | |
<div class="overflow-x-auto"> | |
<table class="w-full" id="investigationTable"> | |
<thead class="bg-gray-100"> | |
<tr> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700">Fase</th> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700">Período</th> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700">Evidências Disponíveis</th> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700">Principal Suspeito</th> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700">Motivo/Justificativa</th> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700">Status da Conclusão</th> | |
<th class="px-4 py-3 text-left font-semibold text-gray-700 print-hidden">Ações</th> | |
</tr> | |
</thead> | |
<tbody id="investigationTableBody"> | |
<!-- Rows will be added dynamically --> | |
</tbody> | |
</table> | |
</div> | |
<div id="emptyState" class="p-8 text-center text-gray-500"> | |
<i data-lucide="search" class="w-12 h-12 mx-auto mb-4 text-gray-300"></i> | |
<p>Nenhuma fase investigativa adicionada ainda.</p> | |
<p class="text-sm">Use o formulário acima para começar a documentar o caso.</p> | |
</div> | |
</div> | |
<!-- Principles Section --> | |
<div class="mt-8 bg-white rounded-lg shadow-lg p-6"> | |
<h2 class="text-2xl font-bold mb-4 text-gray-800 flex items-center"> | |
<i data-lucide="book-open" class="w-6 h-6 mr-2"></i>Princípios da Derrotabilidade Aplicados | |
</h2> | |
<div class="grid md:grid-cols-2 gap-6"> | |
<div class="space-y-4"> | |
<div class="flex items-start space-x-3"> | |
<div class="w-3 h-3 bg-blue-500 rounded-full mt-1.5 flex-shrink-0"></div> | |
<div> | |
<h3 class="font-semibold text-gray-800">Conclusões Racionais mas Revisíveis</h3> | |
<p class="text-sm text-gray-600">Cada hipótese deve ser lógica baseada nas evidências disponíveis no momento, mas sempre passível de revisão.</p> | |
</div> | |
</div> | |
<div class="flex items-start space-x-3"> | |
<div class="w-3 h-3 bg-green-500 rounded-full mt-1.5 flex-shrink-0"></div> | |
<div> | |
<h3 class="font-semibold text-gray-800">Não Monotonia</h3> | |
<p class="text-sm text-gray-600">Novas evidências podem alterar completamente as conclusões anteriores, invalidando hipóteses previamente aceitas.</p> | |
</div> | |
</div> | |
</div> | |
<div class="space-y-4"> | |
<div class="flex items-start space-x-3"> | |
<div class="w-3 h-3 bg-yellow-500 rounded-full mt-1.5 flex-shrink-0"></div> | |
<div> | |
<h3 class="font-semibold text-gray-800">Contexto Dinâmico</h3> | |
<p class="text-sm text-gray-600">A investigação deve evoluir conforme novas informações emergem, mantendo flexibilidade analítica.</p> | |
</div> | |
</div> | |
<div class="flex items-start space-x-3"> | |
<div class="w-3 h-3 bg-red-500 rounded-full mt-1.5 flex-shrink-0"></div> | |
<div> | |
<h3 class="font-semibold text-gray-800">Proteção contra Erros</h3> | |
<p class="text-sm text-gray-600">A análise contínua e revisão sistemática previnem conclusões precipitadas e injustiças.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Summary Statistics --> | |
<div class="mt-8 bg-white rounded-lg shadow-lg p-6"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center"> | |
<i data-lucide="bar-chart-3" class="w-5 h-5 mr-2"></i>Resumo Estatístico | |
</h2> | |
<div class="grid grid-cols-2 md:grid-cols-4 gap-4"> | |
<div class="text-center p-4 bg-blue-50 rounded-lg"> | |
<div class="text-2xl font-bold text-blue-600" id="totalPhases">0</div> | |
<div class="text-sm text-gray-600">Total de Fases</div> | |
</div> | |
<div class="text-center p-4 bg-green-50 rounded-lg"> | |
<div class="text-2xl font-bold text-green-600" id="activeConclusions">0</div> | |
<div class="text-sm text-gray-600">Conclusões Ativas</div> | |
</div> | |
<div class="text-center p-4 bg-red-50 rounded-lg"> | |
<div class="text-2xl font-bold text-red-600" id="defeatedConclusions">0</div> | |
<div class="text-sm text-gray-600">Conclusões Derrotadas</div> | |
</div> | |
<div class="text-center p-4 bg-yellow-50 rounded-lg"> | |
<div class="text-2xl font-bold text-yellow-600" id="reviewConclusions">0</div> | |
<div class="text-sm text-gray-600">Em Revisão</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Instructions Modal --> | |
<div id="instructionsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> | |
<div class="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto"> | |
<div class="px-6 py-4 bg-blue-600 text-white rounded-t-lg flex justify-between items-center"> | |
<h3 class="text-xl font-bold">Instruções de Uso</h3> | |
<button onclick="toggleModal()" class="text-white hover:text-gray-200"> | |
<i data-lucide="x" class="w-6 h-6"></i> | |
</button> | |
</div> | |
<div class="p-6 space-y-4"> | |
<div class="space-y-2"> | |
<h4 class="font-semibold text-lg text-gray-800">1. Cadastro do Caso</h4> | |
<p class="text-gray-600">Preencha todas as informações básicas do caso no primeiro formulário. Clique em "Salvar Informações" para armazenar os dados localmente.</p> | |
</div> | |
<div class="space-y-2"> | |
<h4 class="font-semibold text-lg text-gray-800">2. Adicionar Fases Investigativas</h4> | |
<p class="text-gray-600">Para cada nova etapa da investigação, utilize o formulário "Adicionar Nova Fase Investigativa". Certifique-se de:</p> | |
<ul class="list-disc pl-5 text-gray-600 space-y-1"> | |
<li>Dar um nome descritivo à fase (ex: "Análise de CCTV")</li> | |
<li>Especificar o período da investigação</li> | |
<li>Listar todas as evidências encontradas (uma por linha)</li> | |
<li>Atribuir o status apropriado à conclusão</li> | |
<li>Justificar a conclusão com argumentos sólidos</li> | |
</ul> | |
</div> | |
<div class="space-y-2"> | |
<h4 class="font-semibold text-lg text-gray-800">3. Visualização e Gestão</h4> | |
<p class="text-gray-600">A linha do tempo mostra todas as fases adicionadas. Você pode:</p> | |
<ul class="list-disc pl-5 text-gray-600 space-y-1"> | |
<li>Editar ou excluir fases</li> | |
<li>Ver estatísticas atualizadas</li> | |
<li>Exportar o caso para PDF ou imprimir</li> | |
</ul> | |
</div> | |
<div class="space-y-2"> | |
<h4 class="font-semibold text-lg text-gray-800">4. Princípios da Derrotabilidade</h4> | |
<p class="text-gray-600">Lembre-se de aplicar os princípios da derrotabilidade em todas as análises:</p> | |
<ul class="list-disc pl-5 text-gray-600 space-y-1"> | |
<li>Conclusões devem ser racionais mas revisíveis</li> | |
<li>Novas evidências podem invalidar conclusões anteriores</li> | |
<li>Manter flexibilidade analítica</li> | |
<li>Prevenir conclusões precipitadas</li> | |
</ul> | |
</div> | |
<div class="bg-blue-50 p-4 rounded-lg"> | |
<p class="text-blue-700">Todos os dados são salvos automaticamente no navegador. Para transferir para outro dispositivo, utilize a função de exportação.</p> | |
</div> | |
</div> | |
<div class="px-6 py-4 bg-gray-50 rounded-b-lg flex justify-end"> | |
<button onclick="toggleModal()" class="btn-primary"> | |
<i data-lucide="check" class="w-4 h-4 inline mr-2"></i>Entendi | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Help Button --> | |
<button onclick="toggleModal()" class="fixed bottom-6 right-6 bg-blue-600 hover:bg-blue-700 text-white p-3 rounded-full shadow-lg print-hidden"> | |
<i data-lucide="help-circle" class="w-6 h-6"></i> | |
</button> | |
<script> | |
// Initialize Lucide icons | |
lucide.createIcons(); | |
let phases = []; | |
let phaseCounter = 0; | |
let caseData = { | |
caseNumber: '', | |
caseDate: '', | |
investigator: '', | |
crimeType: '', | |
caseDescription: '' | |
}; | |
// Load saved data from localStorage | |
function loadSavedData() { | |
const savedCaseData = localStorage.getItem('caseData'); | |
if (savedCaseData) { | |
caseData = JSON.parse(savedCaseData); | |
document.getElementById('caseNumber').value = caseData.caseNumber; | |
document.getElementById('caseDate').value = caseData.caseDate; | |
document.getElementById('investigator').value = caseData.investigator; | |
document.getElementById('crimeType').value = caseData.crimeType; | |
document.getElementById('caseDescription').value = caseData.caseDescription; | |
} | |
const savedPhases = localStorage.getItem('phases'); | |
if (savedPhases) { | |
phases = JSON.parse(savedPhases); | |
phaseCounter = phases.length > 0 ? Math.max(...phases.map(p => p.id)) : 0; | |
renderTable(); | |
updateStatistics(); | |
} | |
} | |
// Set current date as default | |
document.getElementById('caseDate').value = new Date().toISOString().split('T')[0]; | |
// Save case information | |
function saveCaseInfo() { | |
caseData = { | |
caseNumber: document.getElementById('caseNumber').value.trim(), | |
caseDate: document.getElementById('caseDate').value, | |
investigator: document.getElementById('investigator').value.trim(), | |
crimeType: document.getElementById('crimeType').value, | |
caseDescription: document.getElementById('caseDescription').value.trim() | |
}; | |
localStorage.setItem('caseData', JSON.stringify(caseData)); | |
alert('Informações do caso salvas com sucesso!'); | |
} | |
// Clear case information | |
function clearCaseInfo() { | |
if (confirm('Tem certeza que deseja limpar todas as informações do caso?')) { | |
document.getElementById('caseNumber').value = ''; | |
document.getElementById('caseDate').value = new Date().toISOString().split('T')[0]; | |
document.getElementById('investigator').value = ''; | |
document.getElementById('crimeType').value = ''; | |
document.getElementById('caseDescription').value = ''; | |
caseData = { | |
caseNumber: '', | |
caseDate: '', | |
investigator: '', | |
crimeType: '', | |
caseDescription: '' | |
}; | |
localStorage.removeItem('caseData'); | |
} | |
} | |
// Add new investigation phase | |
function addPhase() { | |
const phaseName = document.getElementById('phaseName').value.trim(); | |
const phasePeriod = document.getElementById('phasePeriod').value.trim(); | |
const suspect = document.getElementById('suspect').value.trim(); | |
const evidence = document.getElementById('evidence').value.trim(); | |
const justification = document.getElementById('justification').value.trim(); | |
const status = document.getElementById('conclusionStatus').value; | |
if (!phaseName || !phasePeriod || !suspect || !evidence || !justification) { | |
alert('Por favor, preencha todos os campos obrigatórios.'); | |
return; | |
} | |
const phase = { | |
id: ++phaseCounter, | |
name: phaseName, | |
period: phasePeriod, | |
suspect: suspect, | |
evidence: evidence.split('\n').filter(e => e.trim()), | |
justification: justification, | |
status: status, | |
timestamp: new Date().toLocaleString('pt-BR') | |
}; | |
phases.push(phase); | |
localStorage.setItem('phases', JSON.stringify(phases)); | |
renderTable(); | |
updateStatistics(); | |
clearPhaseForm(); | |
} | |
// Clear phase form | |
function clearPhaseForm() { | |
document.getElementById('phaseName').value = ''; | |
document.getElementById('phasePeriod').value = ''; | |
document.getElementById('suspect').value = ''; | |
document.getElementById('evidence').value = ''; | |
document.getElementById('justification').value = ''; | |
document.getElementById('conclusionStatus').value = 'active'; | |
} | |
// Render investigation table | |
function renderTable() { | |
const tbody = document.getElementById('investigationTableBody'); | |
const emptyState = document.getElementById('emptyState'); | |
if (phases.length === 0) { | |
tbody.innerHTML = ''; | |
emptyState.style.display = 'block'; | |
return; | |
} | |
emptyState.style.display = 'none'; | |
tbody.innerHTML = phases.map(phase => ` | |
<tr class="border-t ${getStatusClass(phase.status)} fade-in"> | |
<td class="px-4 py-3">${phase.name}</td> | |
<td class="px-4 py-3">${phase.period}</td> | |
<td class="px-4 py-3"> | |
<ul class="list-disc pl-5"> | |
${phase.evidence.map(e => `<li>${e}</li>`).join('')} | |
</ul> | |
</td> | |
<td class="px-4 py-3">${phase.suspect}</td> | |
<td class="px-4 py-3">${phase.justification}</td> | |
<td class="px-4 py-3"> | |
<span class="${getStatusBadgeClass(phase.status)}">${getStatusText(phase.status)}</span> | |
</td> | |
<td class="px-4 py-3 print-hidden"> | |
<div class="flex space-x-2"> | |
<button onclick="editPhase(${phase.id})" class="text-blue-600 hover:text-blue-800"> | |
<i data-lucide="edit" class="w-4 h-4"></i> | |
</button> | |
<button onclick="deletePhase(${phase.id})" class="text-red-600 hover:text-red-800"> | |
<i data-lucide="trash-2" class="w-4 h-4"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
`).join(''); | |
// Refresh icons after DOM update | |
lucide.createIcons(); | |
} | |
// Get status CSS class for row | |
function getStatusClass(status) { | |
switch(status) { | |
case 'defeated': return 'conclusion-defeated'; | |
case 'active': return 'conclusion-active'; | |
case 'review': return 'conclusion-review'; | |
default: return ''; | |
} | |
} | |
// Get status badge CSS class | |
function getStatusBadgeClass(status) { | |
switch(status) { | |
case 'defeated': return 'status-badge status-defeated'; | |
case 'active': return 'status-badge status-active'; | |
case 'review': return 'status-badge status-review'; | |
default: return 'status-badge'; | |
} | |
} | |
// Get status text | |
function getStatusText(status) { | |
switch(status) { | |
case 'defeated': return 'Derrotada'; | |
case 'active': return 'Ativa'; | |
case 'review': return 'Em Revisão'; | |
default: return status; | |
} | |
} | |
// Edit phase | |
function editPhase(id) { | |
const phase = phases.find(p => p.id === id); | |
if (!phase) return; | |
document.getElementById('phaseName').value = phase.name; | |
document.getElementById('phasePeriod').value = phase.period; | |
document.getElementById('suspect').value = phase.suspect; | |
document.getElementById('evidence').value = phase.evidence.join('\n'); | |
document.getElementById('justification').value = phase.justification; | |
document.getElementById('conclusionStatus').value = phase.status; | |
// Remove the phase being edited | |
phases = phases.filter(p => p.id !== id); | |
localStorage.setItem('phases', JSON.stringify(phases)); | |
renderTable(); | |
updateStatistics(); | |
// Scroll to form | |
document.getElementById('phaseName').focus(); | |
} | |
// Delete phase | |
function deletePhase(id) { | |
if (confirm('Tem certeza que deseja excluir esta fase investigativa?')) { | |
phases = phases.filter(p => p.id !== id); | |
localStorage.setItem('phases', JSON.stringify(phases)); | |
renderTable(); | |
updateStatistics(); | |
} | |
} | |
// Update statistics | |
function updateStatistics() { | |
document.getElementById('totalPhases').textContent = phases.length; | |
document.getElementById('activeConclusions').textContent = phases.filter(p => p.status === 'active').length; | |
document.getElementById('defeatedConclusions').textContent = phases.filter(p => p.status === 'defeated').length; | |
document.getElementById('reviewConclusions').textContent = phases.filter(p => p.status === 'review').length; | |
} | |
// Print case | |
function printCase() { | |
window.print(); | |
} | |
// Export to PDF (simulated - in a real app you would use a library like jsPDF) | |
function exportToPDF() { | |
alert('Na versão completa, esta função exportaria o caso para PDF. Aqui estamos apenas simulando.'); | |
// In a real implementation: | |
// const doc = new jsPDF(); | |
// doc.text('Relatório do Caso', 10, 10); | |
// ... more PDF generation code ... | |
// doc.save('relatorio-caso.pdf'); | |
} | |
// Toggle instructions modal | |
function toggleModal() { | |
const modal = document.getElementById('instructionsModal'); | |
modal.classList.toggle('hidden'); | |
} | |
// Clear all data | |
function clearAllData() { | |
if (confirm('Tem certeza que deseja limpar TODOS os dados? Isso não pode ser desfeito.')) { | |
localStorage.removeItem('caseData'); | |
localStorage.removeItem('phases'); | |
phases = []; | |
phaseCounter = 0; | |
clearCaseInfo(); | |
clearPhaseForm(); | |
renderTable(); | |
updateStatistics(); | |
} | |
} | |
// Initialize the app | |
document.addEventListener('DOMContentLoaded', () => { | |
loadSavedData(); | |
// Add clear all button to header | |
const headerButtons = document.querySelector('header .flex.space-x-2'); | |
const clearAllBtn = document.createElement('button'); | |
clearAllBtn.className = 'btn-danger'; | |
clearAllBtn.innerHTML = '<i data-lucide="trash-2" class="w-4 h-4 inline mr-2"></i>Limpar Tudo'; | |
clearAllBtn.onclick = clearAllData; | |
headerButtons.insertBefore(clearAllBtn, headerButtons.firstChild); | |
lucide.createIcons(); | |
}); | |
</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-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=alexandremoraisdarosa/derrotabilidadetemplatecaso" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |