Feat: dashboard con gráficos, estructura CBS/Portafolios, semáforo de proyectos y cartera de especialistas
This commit is contained in:
+307
-47
@@ -1,41 +1,149 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load humanize %}
|
||||
|
||||
{% block content %}
|
||||
<div class="header-section" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
|
||||
<h1>Panel de Gestión Administrativa</h1>
|
||||
</div>
|
||||
|
||||
<div class="glass-card tabs-container" style="padding: 2rem;">
|
||||
<nav class="tabs-nav">
|
||||
<button class="tab-btn active" onclick="switchTab(event, 'tab-proyectos')">📁 Proyectos</button>
|
||||
<button class="tab-btn" onclick="switchTab(event, 'tab-responsables')">👥 Colaboradores / Responsables</button>
|
||||
<button class="tab-btn" onclick="switchTab(event, 'tab-config')">⚙️ Configuración</button>
|
||||
<button class="tab-btn" onclick="switchTab(event, 'tab-bitacora')">📜 Bitácora de Auditoría</button>
|
||||
</nav>
|
||||
<style>
|
||||
.sidebar-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 0.8rem 1rem;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
color: var(--efintel-dark);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.sidebar-btn:hover {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
color: var(--efintel-blue);
|
||||
}
|
||||
.sidebar-btn.active {
|
||||
background: rgba(5, 59, 80, 0.08); /* efintel-petroleum with opacity */
|
||||
color: var(--efintel-petroleum);
|
||||
font-weight: 600;
|
||||
border-left: 4px solid var(--efintel-petroleum);
|
||||
}
|
||||
.sidebar-btn i {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
.tab-content {
|
||||
display: none;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="gestion-layout" style="display: grid; grid-template-columns: 260px 1fr; gap: 2rem; align-items: start;">
|
||||
|
||||
<!-- Sidebar Navigation -->
|
||||
<div class="data-card" style="padding: 1rem; position: sticky; top: 2rem; background: white; border-radius: 8px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05);">
|
||||
<nav class="sidebar-nav" style="display: flex; flex-direction: column; gap: 0.25rem;">
|
||||
<button class="sidebar-btn active" onclick="switchTab(event, 'tab-proyectos')">
|
||||
<i data-lucide="folder-kanban"></i> Proyectos y Centros
|
||||
</button>
|
||||
<button class="sidebar-btn" onclick="switchTab(event, 'tab-categorias')">
|
||||
<i data-lucide="tags"></i> Categorías Contables
|
||||
</button>
|
||||
<button class="sidebar-btn" onclick="switchTab(event, 'tab-proveedores')">
|
||||
<i data-lucide="building-2"></i> Proveedores
|
||||
</button>
|
||||
<button class="sidebar-btn" onclick="switchTab(event, 'tab-responsables')">
|
||||
<i data-lucide="users"></i> Responsables
|
||||
</button>
|
||||
<hr style="border: none; border-top: 1px solid var(--efintel-light); margin: 0.75rem 0;" />
|
||||
<button class="sidebar-btn" onclick="switchTab(event, 'tab-config')">
|
||||
<i data-lucide="settings"></i> Configuración General
|
||||
</button>
|
||||
<button class="sidebar-btn" onclick="switchTab(event, 'tab-bitacora')">
|
||||
<i data-lucide="scroll-text"></i> Bitácora de Auditoría
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Main Content Area -->
|
||||
<div class="gestion-content">
|
||||
|
||||
<!-- Pestaña Proyectos -->
|
||||
<div id="tab-proyectos" class="tab-content active">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
|
||||
<h2>Proyectos del Sistema</h2>
|
||||
<a href="{% url 'project_create' %}" class="btn btn-primary">➕ Nuevo Proyecto</a>
|
||||
<h2>Proyectos y Centros de Costo</h2>
|
||||
<a href="{% url 'project_create' %}" class="btn btn-primary">Nuevo Proyecto / Centro</a>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<div class="data-card">
|
||||
<div class="data-table-wrapper">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Código</th>
|
||||
<th>Nombre</th>
|
||||
<th>Descripción</th>
|
||||
<th>Portafolio / Jerarquía</th>
|
||||
<th>Categoría / Especialidad</th>
|
||||
<th>Estado</th>
|
||||
<th>Especialistas Habilitados</th>
|
||||
<th>Encargado (Responsable)</th>
|
||||
<th>Creado Por</th>
|
||||
<th>Última Modificación</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for project in projects %}
|
||||
<tr>
|
||||
<td style="font-weight: 600; color: var(--accent-secondary);">{{ project.name }}</td>
|
||||
<td>{{ project.description|default:"Sin descripción" }}</td>
|
||||
<td style="font-weight: 600; color: var(--efintel-blue);">{{ project.code }}</td>
|
||||
<td style="font-weight: 600; color: var(--accent-secondary);">
|
||||
{% if project.parent %}<span style="color:var(--efintel-gray); margin-right:5px;">↳</span>{% endif %}
|
||||
{{ project.name }}
|
||||
</td>
|
||||
<td>
|
||||
{% if project.parent %}
|
||||
<span style="font-size: 0.85rem; color: var(--efintel-blue); font-weight: 500;">{{ project.parent.code }} - {{ project.parent.name }}</span>
|
||||
{% else %}
|
||||
<span class="badge badge-emerald" style="font-size: 0.75rem;">Portafolio Principal</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if project.category %}
|
||||
<span style="font-size: 0.8rem; font-weight: 600; color: var(--efintel-petroleum);">{{ project.category.code }} - {{ project.category.name }}</span>
|
||||
{% else %}
|
||||
<span style="color: var(--efintel-gray); font-size: 0.75rem; font-style: italic;">Sin asignar</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if project.status == 'ACTIVO' %}
|
||||
<span class="badge badge-emerald"><i class="status-dot green"></i> Activo</span>
|
||||
{% elif project.status == 'PAUSADA' %}
|
||||
<span class="badge badge-amber"><i class="status-dot orange"></i> En Pausa</span>
|
||||
{% else %}
|
||||
<span class="badge badge-red"><i class="status-dot red"></i> Terminado</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if project.category %}
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.25rem; max-width: 250px;">
|
||||
{% for spec in project.category.specialists.all %}
|
||||
<span class="badge badge-blue" style="font-size: 0.7rem; font-weight: 600; padding: 0.15rem 0.35rem; border-radius: 4px;">{{ spec.user.username }}</span>
|
||||
{% empty %}
|
||||
<span style="color: var(--efintel-gray); font-size: 0.75rem; font-style: italic;">Sin especialistas</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<span style="color: var(--efintel-gray); font-size: 0.75rem; font-style: italic;">Asigna una categoría para ver especialistas</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if project.manager %}
|
||||
<span style="font-weight: 500;">{{ project.manager.username }}</span>
|
||||
@@ -43,44 +151,181 @@
|
||||
<em style="color: var(--text-secondary);">No asignado</em>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ project.created_by.username|default:"Sistema" }}</td>
|
||||
<td>{{ project.updated_at|date:"d/m/Y H:i" }}</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<a href="{% url 'project_edit' project.id %}" class="btn btn-outline" style="padding: 0.35rem 0.75rem; font-size: 0.8rem;">✏️ Editar</a>
|
||||
<div style="display: flex; gap: 0.25rem;">
|
||||
<a href="{% url 'project_edit' project.id %}" class="btn-icon" title="Editar" style="color: var(--efintel-blue); padding: 0.4rem; border-radius: 4px; transition: background 0.2s;">
|
||||
<i data-lucide="edit-3" style="width: 16px;"></i>
|
||||
</a>
|
||||
<form action="{% url 'project_delete' project.id %}" method="POST" style="display: inline;" onsubmit="return confirm('¿Estás seguro de que deseas eliminar este proyecto? Se eliminarán todos los gastos asociados.');">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-danger" style="padding: 0.35rem 0.75rem; font-size: 0.8rem;">🗑️ Eliminar</button>
|
||||
<button type="submit" class="btn-icon" title="Eliminar" style="color: var(--efintel-danger); padding: 0.4rem; border-radius: 4px; transition: background 0.2s; background: transparent; border: none; cursor: pointer;">
|
||||
<i data-lucide="trash-2" style="width: 16px;"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="6" style="text-align: center;">No hay proyectos registrados.</td>
|
||||
<td colspan="8" style="text-align: center;">No hay proyectos registrados.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pestaña Categorías -->
|
||||
<div id="tab-categorias" class="tab-content">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
|
||||
<div>
|
||||
<h2 style="color: var(--efintel-petroleum); margin-bottom: 0.25rem;">Categorías Contables</h2>
|
||||
<p style="color: var(--efintel-gray); font-size: 0.9rem;">Estructura de imputación financiera.</p>
|
||||
</div>
|
||||
<a href="{% url 'category_create' %}" class="btn-primary" style="text-decoration: none;">
|
||||
<i data-lucide="plus-circle" style="width: 16px;"></i> Nueva Categoría
|
||||
</a>
|
||||
</div>
|
||||
<div class="data-card" style="padding: 0;">
|
||||
<div class="data-table-wrapper" style="margin: 0; padding: 1.5rem;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Código</th>
|
||||
<th>Nombre</th>
|
||||
<th>Partida / Jerarquía</th>
|
||||
<th>Descripción</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for cat in categories %}
|
||||
<tr>
|
||||
<td style="font-weight: 600; color: var(--accent-primary);">{{ cat.code }}</td>
|
||||
<td style="font-weight: 600; color: var(--text-primary);">
|
||||
{% if cat.parent %}<span style="color:var(--efintel-gray); margin-right:5px;">↳</span>{% endif %}
|
||||
{{ cat.name }}
|
||||
</td>
|
||||
<td>
|
||||
{% if cat.parent %}
|
||||
<span style="font-size: 0.85rem; color: var(--efintel-blue); font-weight: 500;">{{ cat.parent.code }} - {{ cat.parent.name }}</span>
|
||||
{% else %}
|
||||
<span class="badge badge-amber" style="font-size: 0.75rem;">Partida Principal</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ cat.description|default:"Sin descripción" }}</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 0.25rem;">
|
||||
<a href="{% url 'category_edit' cat.id %}" class="btn-icon" title="Editar" style="color: var(--efintel-blue); padding: 0.4rem; border-radius: 4px; transition: background 0.2s;">
|
||||
<i data-lucide="edit-3" style="width: 16px;"></i>
|
||||
</a>
|
||||
<form action="{% url 'category_delete' cat.id %}" method="POST" style="display: inline;" onsubmit="return confirm('¿Estás seguro de que deseas eliminar esta categoría? Se podrían perder asociaciones con los gastos.');">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon" title="Eliminar" style="color: var(--efintel-danger); padding: 0.4rem; border-radius: 4px; transition: background 0.2s; background: transparent; border: none; cursor: pointer;">
|
||||
<i data-lucide="trash-2" style="width: 16px;"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="5" style="text-align: center;">No hay categorías registradas.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pestaña Proveedores -->
|
||||
<div id="tab-proveedores" class="tab-content">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
|
||||
<div>
|
||||
<h2 style="color: var(--efintel-petroleum); margin-bottom: 0.25rem;">Directorio de Proveedores</h2>
|
||||
<p style="color: var(--efintel-gray); font-size: 0.9rem;">Registro centralizado de proveedores habilitados.</p>
|
||||
</div>
|
||||
<a href="{% url 'vendor_create' %}" class="btn-primary" style="text-decoration: none;">
|
||||
<i data-lucide="plus-circle" style="width: 16px;"></i> Nuevo Proveedor
|
||||
</a>
|
||||
</div>
|
||||
<div class="data-card" style="padding: 0;">
|
||||
<div class="data-table-wrapper" style="margin: 0; padding: 1.5rem;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>RUT</th>
|
||||
<th>Razón Social</th>
|
||||
<th>Giro Comercial</th>
|
||||
<th>Datos Bancarios</th>
|
||||
<th>Plazo Pago</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for vendor in vendors %}
|
||||
<tr>
|
||||
<td style="font-weight: 600; color: var(--accent-primary);">{{ vendor.rut }}</td>
|
||||
<td style="font-weight: 600; color: var(--text-primary);">{{ vendor.name }}</td>
|
||||
<td>{{ vendor.business_line|default:"-" }}</td>
|
||||
<td>
|
||||
{% if vendor.bank %}
|
||||
<div style="font-size: 0.85rem;">{{ vendor.bank }}</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-secondary);">{{ vendor.account_type }} - {{ vendor.account_number }}</div>
|
||||
{% else %}
|
||||
<em style="color: var(--text-secondary);">No registrados</em>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ vendor.payment_terms }} días</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 0.25rem;">
|
||||
<a href="{% url 'vendor_edit' vendor.id %}" class="btn-icon" title="Editar" style="color: var(--efintel-blue); padding: 0.4rem; border-radius: 4px; transition: background 0.2s;">
|
||||
<i data-lucide="edit-3" style="width: 16px;"></i>
|
||||
</a>
|
||||
<form action="{% url 'vendor_delete' vendor.id %}" method="POST" style="display: inline;" onsubmit="return confirm('¿Estás seguro de que deseas eliminar este proveedor? Sus gastos quedarán huérfanos.');">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon" title="Eliminar" style="color: var(--efintel-danger); padding: 0.4rem; border-radius: 4px; transition: background 0.2s; background: transparent; border: none; cursor: pointer;">
|
||||
<i data-lucide="trash-2" style="width: 16px;"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="6" style="text-align: center;">No hay proveedores registrados.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pestaña Responsables -->
|
||||
<div id="tab-responsables" class="tab-content">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
|
||||
<h2>Responsables y Colaboradores</h2>
|
||||
<a href="{% url 'responsable_create' %}" class="btn btn-primary">➕ Nuevo Responsable</a>
|
||||
<div>
|
||||
<h2 style="color: var(--efintel-petroleum); margin-bottom: 0.25rem;">Responsables y Colaboradores</h2>
|
||||
<p style="color: var(--efintel-gray); font-size: 0.9rem;">Gestión de acceso y roles del personal.</p>
|
||||
</div>
|
||||
<a href="{% url 'responsable_create' %}" class="btn-primary" style="text-decoration: none;">
|
||||
<i data-lucide="plus-circle" style="width: 16px;"></i> Nuevo Responsable
|
||||
</a>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<div class="data-card" style="padding: 0;">
|
||||
<div class="data-table-wrapper" style="margin: 0; padding: 1.5rem;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Usuario</th>
|
||||
<th>Correo</th>
|
||||
<th>Rol / Permiso</th>
|
||||
<th>Especialidades Habilitadas (CBS)</th>
|
||||
<th>Descripción / Bio</th>
|
||||
<th>F. Registro</th>
|
||||
<th>F. Modificación</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -93,27 +338,39 @@
|
||||
{% if resp.groups.all %}
|
||||
{% with role=resp.groups.all.0.name %}
|
||||
{% if role == 'Administrador' %}
|
||||
<span class="badge badge-admin">Administrador</span>
|
||||
<span class="badge badge-red">Administrador</span>
|
||||
{% elif role == 'Director de Proyecto' %}
|
||||
<span class="badge badge-director">Director</span>
|
||||
<span class="badge badge-blue">Director</span>
|
||||
{% else %}
|
||||
<span class="badge badge-gestor">Gestor</span>
|
||||
<span class="badge badge-emerald">Gestor</span>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<span class="badge badge-gestor">Sin Rol</span>
|
||||
<span class="badge badge-amber">Sin Rol</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.25rem; max-width: 250px;">
|
||||
{% for spec in resp.profile.specialties.all %}
|
||||
<span class="badge badge-blue" style="font-size: 0.7rem; padding: 0.15rem 0.35rem;" title="{{ spec.name }}">{{ spec.code }}</span>
|
||||
{% empty %}
|
||||
<span style="color: var(--efintel-gray); font-size: 0.75rem; font-style: italic;">Ninguna</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ resp.profile.description|default:"Sin descripción personal" }}</td>
|
||||
<td>{{ resp.profile.created_at|date:"d/m/Y"|default:"-" }}</td>
|
||||
<td>{{ resp.profile.updated_at|date:"d/m/Y H:i"|default:"-" }}</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<a href="{% url 'responsable_edit' resp.id %}" class="btn btn-outline" style="padding: 0.35rem 0.75rem; font-size: 0.8rem;">✏️ Editar</a>
|
||||
<div style="display: flex; gap: 0.25rem;">
|
||||
<a href="{% url 'responsable_edit' resp.id %}" class="btn-icon" title="Editar" style="color: var(--efintel-blue); padding: 0.4rem; border-radius: 4px; transition: background 0.2s;">
|
||||
<i data-lucide="edit-3" style="width: 16px;"></i>
|
||||
</a>
|
||||
{% if resp != request.user %}
|
||||
<form action="{% url 'responsable_delete' resp.id %}" method="POST" style="display: inline;" onsubmit="return confirm('¿Estás seguro de que deseas eliminar este responsable?');">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-danger" style="padding: 0.35rem 0.75rem; font-size: 0.8rem;">🗑️ Eliminar</button>
|
||||
<button type="submit" class="btn-icon" title="Eliminar" style="color: var(--efintel-danger); padding: 0.4rem; border-radius: 4px; transition: background 0.2s; background: transparent; border: none; cursor: pointer;">
|
||||
<i data-lucide="trash-2" style="width: 16px;"></i>
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -126,21 +383,23 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pestaña Configuración -->
|
||||
<div id="tab-config" class="tab-content">
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h2>Configuración General del Sistema</h2>
|
||||
<h2 style="color: var(--efintel-petroleum); margin-bottom: 0.25rem;">Configuración General del Sistema</h2>
|
||||
<p style="color: var(--efintel-gray); font-size: 0.9rem;">Parámetros y límites globales del ERP.</p>
|
||||
</div>
|
||||
<div style="max-width: 500px; display: flex; flex-direction: column; gap: 1.5rem;">
|
||||
<div class="glass-card" style="padding: 1.5rem; background: rgba(0, 0, 0, 0.2);">
|
||||
<div class="data-card" style="padding: 2rem;">
|
||||
<div style="color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.5rem;">Presupuesto General Asignado</div>
|
||||
<div style="font-size: 2rem; font-weight: 700; color: var(--accent-secondary);">${{ settings.global_budget|default:"100000.00" }}</div>
|
||||
<div style="font-size: 2.5rem; font-weight: 700; color: var(--efintel-petroleum);">${{ settings.global_budget|floatformat:"0"|intcomma|default:"100000" }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{% url 'settings_edit' %}" class="btn btn-primary">✏️ Modificar Presupuesto General</a>
|
||||
<a href="{% url 'settings_edit' %}" class="btn-primary" style="text-decoration: none;">Modificar Presupuesto General</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -148,20 +407,20 @@
|
||||
<!-- Pestaña Bitácora -->
|
||||
<div id="tab-bitacora" class="tab-content">
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h2>Bitácora de Auditoría y Trazabilidad (Logs)</h2>
|
||||
<h2 style="color: var(--efintel-petroleum); margin-bottom: 0.25rem;">Bitácora de Auditoría y Trazabilidad (Logs)</h2>
|
||||
<p style="color: var(--text-secondary); font-size: 0.9rem;">Historial detallado de operaciones realizadas por los administradores en el sistema.</p>
|
||||
</div>
|
||||
<div class="log-list">
|
||||
<div class="data-card" style="padding: 1.5rem;">
|
||||
{% for log in logs %}
|
||||
<div class="log-item">
|
||||
<div class="log-info">
|
||||
<div class="log-action">
|
||||
{% if "Creado" in log.action or "Creación" in log.action %}
|
||||
🟢 {{ log.action }}
|
||||
{{ log.action }}
|
||||
{% elif "Eliminado" in log.action or "Eliminación" in log.action %}
|
||||
🔴 {{ log.action }}
|
||||
{{ log.action }}
|
||||
{% else %}
|
||||
🟡 {{ log.action }}
|
||||
{{ log.action }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="log-desc">{{ log.description }}</div>
|
||||
@@ -176,7 +435,8 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- End Main Content Area -->
|
||||
</div> <!-- End Gestion Layout -->
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
@@ -187,7 +447,7 @@
|
||||
contents.forEach(content => content.classList.remove('active'));
|
||||
|
||||
// Desactivar todos los botones de pestaña
|
||||
const buttons = document.querySelectorAll('.tab-btn');
|
||||
const buttons = document.querySelectorAll('.sidebar-btn');
|
||||
buttons.forEach(btn => btn.classList.remove('active'));
|
||||
|
||||
// Activar pestaña actual
|
||||
@@ -202,7 +462,7 @@
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const activeTab = localStorage.getItem('activeTab');
|
||||
if (activeTab && document.getElementById(activeTab)) {
|
||||
const btn = Array.from(document.querySelectorAll('.tab-btn')).find(b => b.getAttribute('onclick').includes(activeTab));
|
||||
const btn = Array.from(document.querySelectorAll('.sidebar-btn')).find(b => b.getAttribute('onclick').includes(activeTab));
|
||||
if (btn) {
|
||||
// Simular clic en el botón
|
||||
btn.click();
|
||||
|
||||
Reference in New Issue
Block a user