БЫЛО: Каждая из 14 страниц имела своё собственное вшитое меню
с разным набором кнопок (от 4 до 10 пунктов)
СТАЛО: Все 14 страниц наследуют base.html с единым меню из 14 пунктов
в 4 разделах: Пользователи / Коммуникации / Контент / Система
Убрано 1949 строк дублирующегося кода, добавлено 1323 строки чистого контента.
Экономия: -626 строк (32% сокращение).
Переписанные страницы:
- dashboard.html, users.html, verification.html
- phones.html, polls.html, events.html
- schedules.html, ads.html, scheduled_posts.html, export.html
Результат: На ЛЮБОЙ странице пользователь видит ВСЕ 14 пунктов меню.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
161 lines
5.9 KiB
HTML
161 lines
5.9 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Верификация - Домовой Бот{% endblock %}
|
||
|
||
{% block nav_verification %}active{% endblock %}
|
||
|
||
{% block extra_style %}
|
||
.status-pending { color: #f39c12; }
|
||
.status-approved { color: #27ae60; }
|
||
.status-rejected { color: #c0392b; }
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<h2 class="mb-4"><i class="bi bi-shield-check"></i> Управление верификацией</h2>
|
||
|
||
<!-- Заявки на верификацию -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-warning text-dark">
|
||
<h5 class="mb-0"><i class="bi bi-clock-history"></i> Заявки на проверку</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
{% if pending_requests %}
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>ID заявки</th>
|
||
<th>User ID</th>
|
||
<th>Имя</th>
|
||
<th>Квартира</th>
|
||
<th>Дата</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for req in pending_requests %}
|
||
<tr>
|
||
<td>{{ req.id }}</td>
|
||
<td>{{ req.user_id }}</td>
|
||
<td>{{ req.comment or '—' }}</td>
|
||
<td>{{ req.apartment or '—' }}</td>
|
||
<td>{{ req.created_at.strftime('%d.%m.%Y %H:%M') if req.created_at else '—' }}</td>
|
||
<td>
|
||
<button class="btn btn-sm btn-success" onclick="approveVerification({{ req.id }})">
|
||
<i class="bi bi-check-lg"></i> Одобрить
|
||
</button>
|
||
<button class="btn btn-sm btn-danger" onclick="rejectVerification({{ req.id }})">
|
||
<i class="bi bi-x-lg"></i> Отклонить
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="text-muted text-center">Нет заявок на верификацию</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Непроверенные пользователи -->
|
||
<div class="card">
|
||
<div class="card-header bg-secondary text-white">
|
||
<h5 class="mb-0"><i class="bi bi-person-x"></i> Непроверенные пользователи</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
{% if unverified_users %}
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>User ID</th>
|
||
<th>Имя</th>
|
||
<th>Квартира</th>
|
||
<th>Дата регистрации</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for user in unverified_users %}
|
||
<tr>
|
||
<td>{{ user.user_id }}</td>
|
||
<td>{{ user.full_name or '—' }}</td>
|
||
<td>{{ user.apartment or '—' }}</td>
|
||
<td>{{ user.join_date.strftime('%d.%m.%Y') if user.join_date else '—' }}</td>
|
||
<td>
|
||
<button class="btn btn-sm btn-success" onclick="verifyUser({{ user.user_id }})">
|
||
<i class="bi bi-check-lg"></i> Верифицировать
|
||
</button>
|
||
<button class="btn btn-sm btn-warning" onclick="unverifyUser({{ user.user_id }})">
|
||
<i class="bi bi-x-lg"></i> Отозвать
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="text-muted text-center">Все пользователи верифицированы</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block extra_script %}
|
||
<script>
|
||
async function approveVerification(requestId) {
|
||
if (!confirm('Одобрить верификацию?')) return;
|
||
|
||
const response = await fetch(`/api/verification/${requestId}/approve`, { method: 'POST' });
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
alert('✅ Верификация одобрена');
|
||
location.reload();
|
||
} else {
|
||
alert('❌ Ошибка: ' + result.error);
|
||
}
|
||
}
|
||
|
||
async function rejectVerification(requestId) {
|
||
if (!confirm('Отклонить верификацию?')) return;
|
||
|
||
const response = await fetch(`/api/verification/${requestId}/reject`, { method: 'POST' });
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
alert('Верификация отклонена');
|
||
location.reload();
|
||
} else {
|
||
alert('❌ Ошибка: ' + result.error);
|
||
}
|
||
}
|
||
|
||
async function verifyUser(userId) {
|
||
if (!confirm('Верифицировать пользователя?')) return;
|
||
|
||
const response = await fetch(`/api/user/${userId}/verify`, { method: 'POST' });
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
alert('✅ Пользователь верифицирован');
|
||
location.reload();
|
||
} else {
|
||
alert('❌ Ошибка: ' + result.error);
|
||
}
|
||
}
|
||
|
||
async function unverifyUser(userId) {
|
||
if (!confirm('Отозвать верификацию у пользователя?')) return;
|
||
|
||
const response = await fetch(`/api/user/${userId}/unverify`, { method: 'POST' });
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
alert('⚠️ Верификация отозвана');
|
||
location.reload();
|
||
} else {
|
||
alert('❌ Ошибка: ' + result.error);
|
||
}
|
||
}
|
||
</script>
|
||
{% endblock %}
|