ATS/templates/includes/easy_logs.html
2026-02-01 13:38:06 +03:00

194 lines
12 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}{% trans "Audit Dashboard" %}{% endblock %}
{% block content %}
<!-- Breadcrumb -->
<nav aria-label="breadcrumb" class="mb-4">
<ol class="flex items-center gap-2 text-sm">
<li>
<a href="{% url 'settings' %}" class="text-gray-600 hover:text-temple-red transition">{% trans "Settings" %}</a>
</li>
<li class="text-gray-400">/</li>
<li class="font-semibold text-temple-red">{% trans "System Activity" %}</li>
</ol>
</nav>
<!-- Header -->
<div class="mb-4">
<h1 class="text-2xl font-bold text-gray-900 flex items-center gap-2">
<i data-lucide="shield" class="w-6 h-6 text-temple-red"></i>
{% trans "System Activity Logs" %}
</h1>
</div>
<!-- Summary Alert -->
<div class="bg-temple-red/10 border-l-4 border-temple-red p-4 mb-6 rounded-r-lg">
<div class="text-sm font-semibold text-gray-800 mb-1">
{% trans "Viewing Logs" %}: <strong>{{ tab_title }}</strong>
</div>
<p class="text-sm text-gray-700">
{% trans "Displaying" %}: <strong>{{ logs.start_index }}-{{ logs.end_index }}</strong> {% trans "of" %}
<strong>{{ total_count }}</strong> {% trans "total records." %}
</p>
</div>
<!-- Audit Card -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 min-h-[60vh]">
<!-- Tabs -->
<div class="flex border-b border-gray-200 px-3 pt-4 rounded-t-xl">
<a class="px-4 py-2 text-sm font-medium transition border-b-3 {% if active_tab == 'crud' %}text-temple-red border-temple-red{% else %}text-gray-600 border-transparent hover:text-temple-red hover:border-gray-300{% endif %}"
href="?tab=crud">
<i data-lucide="database" class="w-4 h-4 inline mr-2"></i>{% trans "Model Changes (CRUD)" %}
</a>
<a class="px-4 py-2 text-sm font-medium transition border-b-3 {% if active_tab == 'login' %}text-temple-red border-temple-red{% else %}text-gray-600 border-transparent hover:text-temple-red hover:border-gray-300{% endif %}"
href="?tab=login">
<i data-lucide="user-lock" class="w-4 h-4 inline mr-2"></i>{% trans "User Authentication" %}
</a>
<a class="px-4 py-2 text-sm font-medium transition border-b-3 {% if active_tab == 'request' %}text-temple-red border-temple-red{% else %}text-gray-600 border-transparent hover:text-temple-red hover:border-gray-300{% endif %}"
href="?tab=request">
<i data-lucide="globe" class="w-4 h-4 inline mr-2"></i>{% trans "HTTP Requests" %}
</a>
</div>
<!-- Tab Content -->
<div class="p-4">
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
{% if active_tab == 'crud' %}
<tr class="bg-gray-50">
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Date/Time" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "User" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Action" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Model" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Object PK" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Changes" %}</th>
</tr>
{% elif active_tab == 'login' %}
<tr class="bg-gray-50">
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Date/Time" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "User" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Type" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Status" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "IP Address" %}</th>
</tr>
{% elif active_tab == 'request' %}
<tr class="bg-gray-50">
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Date/Time" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "User" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Method" %}</th>
<th class="px-4 py-3 text-left font-semibold text-gray-700">{% trans "Path" %}</th>
</tr>
{% endif %}
</thead>
<tbody class="divide-y divide-gray-100">
{% for log in logs.object_list %}
{% if active_tab == 'crud' %}
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-gray-900">{{ log.datetime|date:"Y-m-d H:i:s" }}</td>
<td class="px-4 py-3 text-gray-900">{{ log.user.email|default:"N/A" }}</td>
<td class="px-4 py-3">
{% if log.event_type == 1 %}
<span class="inline-flex items-center gap-1 px-2.5 py-1 bg-green-100 text-green-800 rounded-full text-xs font-medium"><i data-lucide="plus" class="w-3 h-3"></i>{% trans "CREATE" %}</span>
{% elif log.event_type == 2 %}
<span class="inline-flex items-center gap-1 px-2.5 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs font-medium"><i data-lucide="edit" class="w-3 h-3"></i>{% trans "UPDATE" %}</span>
{% else %}
<span class="inline-flex items-center gap-1 px-2.5 py-1 bg-red-100 text-red-800 rounded-full text-xs font-medium"><i data-lucide="trash-2" class="w-3 h-3"></i>{% trans "DELETE" %}</span>
{% endif %}
</td>
<td class="px-4 py-3"><code class="bg-gray-100 px-2 py-1 rounded text-xs">{{ log.content_type.app_label }}.{{ log.content_type.model }}</code></td>
<td class="px-4 py-3 text-gray-900">{{ log.object_id }}</td>
<td class="px-4 py-3">
<pre class="bg-gray-100 p-2 rounded text-xs overflow-x-auto max-h-20 overflow-y-auto">{{ log.changed_fields }}</pre>
</td>
</tr>
{% elif active_tab == 'login' %}
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-gray-900">{{ log.datetime|date:"Y-m-d H:i:s" }}</td>
<td class="px-4 py-3 text-gray-900">
{% with user_obj=log.user %}
{% if user_obj %}
{{ user_obj.get_full_name|default:user_obj.username }}
{% else %}
<span class="text-red-600 font-semibold">{{ log.username|default:"N/A" }}</span>
{% endif %}
{% endwith %}
</td>
<td class="px-4 py-3">
<span class="inline-block px-2.5 py-1 bg-gray-700 text-white rounded-full text-xs font-medium">
{% if log.login_type == 0 %}{% trans "Login" %}
{% elif log.login_type == 1 %}{% trans "Logout" %}
{% else %}{% trans "Failed Login" %}{% endif %}
</span>
</td>
<td class="px-4 py-3">
{% if log.login_type == 2 %}
<span class="inline-flex items-center gap-1 text-red-600"><i data-lucide="x-circle" class="w-4 h-4"></i>{% trans "Failed" %}</span>
{% else %}
<span class="inline-flex items-center gap-1 text-green-600"><i data-lucide="check-circle" class="w-4 h-4"></i>{% trans "Success" %}</span>
{% endif %}
</td>
<td class="px-4 py-3 text-gray-900">{{ log.remote_ip|default:"Unknown" }}</td>
</tr>
{% elif active_tab == 'request' %}
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-gray-900">{{ log.datetime|date:"Y-m-d H:i:s" }}</td>
<td class="px-4 py-3 text-gray-900">{{ log.user.get_full_name|default:log.user.email|default:"Anonymous" }}</td>
<td class="px-4 py-3">
<span class="inline-block px-2.5 py-1 bg-gray-700 text-white rounded-full text-xs font-medium">{{ log.method }}</span>
</td>
<td class="px-4 py-3"><code class="bg-gray-100 px-2 py-1 rounded text-xs break-all">{{ log.url}}</code></td>
</tr>
{% endif %}
{% empty %}
<tr>
<td colspan="6" class="px-4 py-12 text-center text-gray-500">
<i data-lucide="info" class="w-5 h-5 inline mr-2"></i>{% trans "No logs found for this section or database is empty." %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if logs.has_other_pages %}
<div class="flex justify-end items-center gap-2 pt-4">
<a href="?tab={{ active_tab }}{% if logs.has_previous %}&page={{ logs.previous_page_number }}{% endif %}"
class="px-3 py-2 text-sm font-medium rounded-lg {% if logs.has_previous %}bg-white border border-gray-300 text-temple-red hover:bg-gray-50{% else %}bg-gray-100 text-gray-400 cursor-not-allowed{% endif %} transition">
<i data-lucide="chevron-left" class="w-4 h-4 inline"></i>
</a>
{% for i in logs.paginator.page_range %}
{% if i > logs.number|add:'-3' and i < logs.number|add:'3' %}
<a href="?tab={{ active_tab }}&page={{ i }}"
class="px-3 py-2 text-sm font-medium rounded-lg {% if logs.number == i %}bg-temple-red text-white{% else %}bg-white border border-gray-300 text-temple-red hover:bg-gray-50{% endif %} transition">
{{ i }}
</a>
{% elif i == logs.number|add:'-3' or i == logs.number|add:'3' %}
<span class="px-3 py-2 text-sm text-gray-400">...</span>
{% endif %}
{% endfor %}
<a href="?tab={{ active_tab }}{% if logs.has_next %}&page={{ logs.next_page_number }}{% endif %}"
class="px-3 py-2 text-sm font-medium rounded-lg {% if logs.has_next %}bg-white border border-gray-300 text-temple-red hover:bg-gray-50{% else %}bg-gray-100 text-gray-400 cursor-not-allowed{% endif %} transition">
<i data-lucide="chevron-right" class="w-4 h-4 inline"></i>
</a>
</div>
{% endif %}
</div>
</div>
<script>
lucide.createIcons();
</script>
{% endblock %}