v1.8.4: единая стилистика — замена confirm/alert/prompt на кастомные модалки, SERVICE_STYLE_GUIDE.md, обновлен AGENTS.md
Tests / test (push) Has been cancelled
Tests / test-max-bot (push) Has been cancelled

This commit is contained in:
2026-06-02 20:40:24 +03:00
parent df34048e2a
commit e184e5fe79
23 changed files with 777 additions and 70 deletions
@@ -31,6 +31,14 @@
.confirm-modal .confirm-actions { display:flex; gap:10px; justify-content:center; }
.confirm-modal .confirm-actions .btn { min-width:140px; }
.timer-danger { color:var(--danger) !important; }
.modal-overlay { display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.5); z-index:1000; align-items:center; justify-content:center; }
.modal-overlay.open { display:flex; }
.modal { background:var(--bg-card); border:1px solid var(--border); border-radius:12px; padding:24px; width:420px; max-width:90vw; }
.modal h2 { color:var(--text-primary); }
.modal p { color:var(--text-secondary); }
.modal-actions { display:flex; gap:10px; }
.btn-danger { background:var(--danger, #dc3545); color:#fff; border:none; padding:8px 16px; border-radius:6px; cursor:pointer; font-weight:600; }
.btn { background:var(--bg-input); color:var(--text-primary); border:1px solid var(--border); padding:8px 16px; border-radius:6px; cursor:pointer; }
</style>
<div class="card">
@@ -93,10 +101,27 @@
</div>
</div>
<div class="modal-overlay" id="confirm-delete-user">
<div class="modal" style="max-width:420px;">
<h2 style="font-size:16px;margin-bottom:8px;">Удалить пользователя?</h2>
<p style="color:var(--text-secondary);font-size:14px;margin-bottom:20px;">
<strong id="delete-user-name"></strong> (ID: <span id="delete-user-id"></span>) будет удалён навсегда.
Все его диалоги и сообщения будут удалены. Заявки останутся.
Это действие нельзя отменить.
</p>
<div class="modal-actions" style="justify-content:flex-end;">
<button type="button" class="btn btn-danger" onclick="confirmDeleteUser()">Удалить</button>
<button type="button" class="btn" onclick="closeConfirmDeleteUser()">Отмена</button>
</div>
</div>
</div>
<script>
var allConsents = [];
var confirmTimer = null;
var confirmSeconds = 10;
var pendingDeleteUserId = null;
var pendingDeleteUserName = null;
function loadConsents(){
var tbody = document.getElementById('consent-table-body');
@@ -135,7 +160,7 @@ function renderConsents(list){
'<td class="consent-yes">Да</td>' +
'<td style="font-size:12px;color:var(--text-muted);">' + dateStr + '</td>';
if(USER_ROLE === 'owner'){
html += '<td><button class="btn btn-danger btn-sm" onclick="confirmDeleteUser(' + u.id + ', \'' + escapeHtml(name).replace(/'/g, "\\'") + '\')" title="Удалить пользователя">🗑</button></td>';
html += '<td><button class="btn btn-danger btn-sm" onclick="openConfirmDeleteUser(' + u.id + ', \'' + escapeHtml(name).replace(/'/g, "\\'") + '\')" title="Удалить пользователя">🗑</button></td>';
}
html += '</tr>';
});
@@ -222,8 +247,24 @@ function escapeHtml(s){
return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
function confirmDeleteUser(userId, userName){
if(!confirm('Удалить пользователя ' + userName + ' (ID: ' + userId + ')?\n\nВсе его диалоги и сообщения будут удалены навсегда. Заявки останутся.')) return;
function openConfirmDeleteUser(userId, userName){
pendingDeleteUserId = userId;
pendingDeleteUserName = userName;
document.getElementById('delete-user-name').textContent = userName;
document.getElementById('delete-user-id').textContent = userId;
document.getElementById('confirm-delete-user').classList.add('open');
}
function closeConfirmDeleteUser(){
document.getElementById('confirm-delete-user').classList.remove('open');
pendingDeleteUserId = null;
pendingDeleteUserName = null;
}
function confirmDeleteUser(){
var userId = pendingDeleteUserId;
var userName = pendingDeleteUserName;
closeConfirmDeleteUser();
fetch('/api/bot/users/' + userId, { method: 'DELETE' })
.then(function(r){ return r.json() })
.then(function(d){