Files
evo-sync/web/templates/admin/logs.html
mguschin eb4165e48b feat: apply new Мои Товары design system across all templates
Replace Pico CSS with custom design: dark sidebar layout, Golos Text +
JetBrains Mono fonts, orange accent (#FF5500), new component classes
(cards, tables, buttons, tags, toggles, alerts, tabs, login split-panel).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:43:08 +03:00

148 lines
7.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}API Логи — Мои Товары{% endblock %}
{% block page_title %}API Логи{% endblock %}
{% block content %}
<div class="pg-title">API Логи</div>
<div class="pg-sub">Журнал всех исходящих запросов · Найдено: {{ total }}</div>
<!-- Filters -->
<div class="card" style="margin-bottom:14px;padding:14px 20px;">
<form method="get" action="/admin/logs" style="display:flex;flex-wrap:wrap;gap:8px;align-items:center;">
<select class="inp" name="service" style="width:auto;">
<option value="" {% if not filter_service %}selected{% endif %}>Все сервисы</option>
<option value="evotor" {% if filter_service == 'evotor' %}selected{% endif %}>Эвотор</option>
<option value="vk" {% if filter_service == 'vk' %}selected{% endif %}>ВКонтакте</option>
<option value="other" {% if filter_service == 'other' %}selected{% endif %}>Другое</option>
</select>
<select class="inp" name="method" style="width:auto;">
<option value="" {% if not filter_method %}selected{% endif %}>Все методы</option>
<option value="GET" {% if filter_method == 'GET' %}selected{% endif %}>GET</option>
<option value="POST" {% if filter_method == 'POST' %}selected{% endif %}>POST</option>
</select>
<select class="inp" name="status" style="width:auto;">
<option value="" {% if not filter_status %}selected{% endif %}>Любой статус</option>
<option value="ok" {% if filter_status == 'ok' %}selected{% endif %}>2xx / 3xx</option>
<option value="error" {% if filter_status == 'error' %}selected{% endif %}>4xx / 5xx</option>
<option value="200" {% if filter_status == '200' %}selected{% endif %}>200</option>
<option value="401" {% if filter_status == '401' %}selected{% endif %}>401</option>
<option value="403" {% if filter_status == '403' %}selected{% endif %}>403</option>
<option value="429" {% if filter_status == '429' %}selected{% endif %}>429</option>
<option value="500" {% if filter_status == '500' %}selected{% endif %}>500</option>
</select>
<select class="inp" name="hours" style="width:auto;">
<option value="1" {% if filter_hours == 1 %}selected{% endif %}>Последний час</option>
<option value="6" {% if filter_hours == 6 %}selected{% endif %}>6 часов</option>
<option value="24" {% if filter_hours == 24 %}selected{% endif %}>24 часа</option>
<option value="168" {% if filter_hours == 168 or (not filter_hours) %}selected{% endif %}>7 дней</option>
<option value="720" {% if filter_hours == 720 %}selected{% endif %}>30 дней</option>
</select>
<input class="inp" type="search" name="q" value="{{ filter_q }}"
placeholder="URL или тело ответа…" style="flex:1;min-width:160px;">
<button type="submit" class="btn btn-primary btn-sm">Применить</button>
{% if filter_service or filter_method or filter_status or filter_q or filter_hours != 24 %}
<a href="/admin/logs" class="btn btn-outline btn-sm">Сбросить</a>
{% endif %}
</form>
</div>
<div class="card" style="padding:0;">
{% if logs %}
<div class="table-wrap">
<table class="tbl" style="font-size:12px;">
<thead>
<tr>
<th style="width:150px;">Время</th>
<th style="width:80px;">Сервис</th>
<th style="width:50px;">Метод</th>
<th style="width:60px;">Статус</th>
<th style="width:70px;">Мс</th>
<th>URL</th>
<th style="width:32px;"></th>
</tr>
</thead>
<tbody>
{% for log in logs %}
{% set is_error = log.response_status and log.response_status >= 400 %}
<tr style="cursor:pointer;" onclick="toggleDetail({{ log.id }})">
<td><span class="mono" style="font-size:11px;color:#9EA8BE;">{{ log.created_at | datefmt }}</span></td>
<td>
{% if log.service == 'evotor' %}
<span class="tag tag-bl" style="font-size:10px;padding:2px 6px;">{{ log.service }}</span>
{% elif log.service == 'vk' %}
<span class="tag tag-or" style="font-size:10px;padding:2px 6px;">{{ log.service }}</span>
{% else %}
<span class="tag tag-dim" style="font-size:10px;padding:2px 6px;">{{ log.service }}</span>
{% endif %}
</td>
<td><span class="mono" style="font-size:11px;">{{ log.method }}</span></td>
<td>
{% if log.response_status %}
<span class="mono" style="font-size:11px;color:{% if is_error %}#E53935{% else %}#17A865{% endif %};">{{ log.response_status }}</span>
{% else %}
<span style="color:#9EA8BE;"></span>
{% endif %}
</td>
<td><span class="mono" style="font-size:11px;color:#9EA8BE;">{{ log.duration_ms if log.duration_ms is not none else '—' }}</span></td>
<td style="max-width:400px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
<span class="mono" style="font-size:11px;{% if is_error %}color:#E53935;{% endif %}" title="{{ log.url }}">{{ log.url }}</span>
</td>
<td style="color:#9EA8BE;"><i class="bi bi-chevron-down"></i></td>
</tr>
<tr id="detail-{{ log.id }}" style="display:none;background:#F9FAFB;">
<td colspan="7" style="padding:14px 20px;">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
<div>
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.06em;color:#9EA8BE;margin-bottom:6px;">URL</div>
<code style="word-break:break-all;font-size:11px;">{{ log.url }}</code>
{% if log.request_body %}
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.06em;color:#9EA8BE;margin:10px 0 6px;">Request body</div>
<pre style="font-size:11px;max-height:180px;overflow:auto;">{{ log.request_body }}</pre>
{% endif %}
</div>
<div>
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.06em;color:#9EA8BE;margin-bottom:6px;">Response ({{ log.response_status }})</div>
{% if log.response_body %}
<pre style="font-size:11px;max-height:180px;overflow:auto;">{{ log.response_body }}</pre>
{% else %}
<span style="color:#9EA8BE;font-size:12px;"></span>
{% endif %}
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if total_pages > 1 %}
<div class="pagination">
{% if page > 1 %}
<a href="?service={{ filter_service }}&method={{ filter_method }}&status={{ filter_status }}&q={{ filter_q }}&hours={{ filter_hours }}&page={{ page - 1 }}" class="btn btn-outline btn-sm">← Назад</a>
{% endif %}
<span style="font-size:12px;color:#9EA8BE;">Стр. {{ page }} / {{ total_pages }}</span>
{% if page < total_pages %}
<a href="?service={{ filter_service }}&method={{ filter_method }}&status={{ filter_status }}&q={{ filter_q }}&hours={{ filter_hours }}&page={{ page + 1 }}" class="btn btn-outline btn-sm">Вперёд →</a>
{% endif %}
</div>
{% endif %}
{% else %}
<div class="empty-state">
<i class="bi bi-journal-x"></i>
<p>Записей не найдено за выбранный период.</p>
</div>
{% endif %}
</div>
{% endblock %}
{% block scripts %}
<script>
function toggleDetail(id) {
const row = document.getElementById('detail-' + id);
row.style.display = row.style.display === 'none' ? 'table-row' : 'none';
}
</script>
{% endblock %}