v2: EJS-шаблоны — user, admin, admin-audit, admin-entries
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8"><title>Аудит — <%= company ? company.client_id : 'Все' %> — v<%= version %></title>
|
||||
<style>
|
||||
body{font-family:sans-serif;max-width:1200px;margin:20px auto;color:#222}
|
||||
table{width:100%;border-collapse:collapse;margin:10px 0}
|
||||
th,td{border:1px solid #ccc;padding:6px;text-align:left;font-size:13px}
|
||||
th{background:#263238;color:#fff}
|
||||
.bar{display:flex;justify-content:space-between;align-items:center;background:#263238;color:#fff;padding:10px;margin-bottom:15px}
|
||||
.bar a{color:#80cbc4}
|
||||
</style></head><body>
|
||||
<div class="bar">
|
||||
<span><strong>📋 Аудит</strong> <%= company ? company.client_id : 'Все компании' %></span>
|
||||
<span><a href="/v2/admin">← Админка</a> | <a href="/v2/app">Пользовательский</a></span>
|
||||
</div>
|
||||
<table>
|
||||
<tr><th>Дата</th><th>Действие</th><th>Кто</th><th>От имени</th><th>Компания</th><th>Значения</th></tr>
|
||||
<% if (audit.length === 0) { %><tr><td colspan="6">Нет записей</td></tr><% } %>
|
||||
<% audit.forEach(function(a) { %>
|
||||
<tr>
|
||||
<td><%= new Date(a.created_at).toLocaleString('ru') %></td>
|
||||
<td><strong><%= a.action %></strong></td>
|
||||
<td><%= a.user_email %></td>
|
||||
<td><%= a.impersonated_by || '—' %></td>
|
||||
<td><%= a.company_name || '—' %></td>
|
||||
<td><%= a.old_value || '—' %> → <%= a.new_value || '—' %></td>
|
||||
</tr>
|
||||
<% }) %>
|
||||
</table>
|
||||
<p>Показано: <%= audit.length %> (макс 500)</p>
|
||||
</body></html>
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8"><title>Записи — <%= company.client_id %> — v<%= version %></title>
|
||||
<style>
|
||||
body{font-family:sans-serif;max-width:1000px;margin:20px auto;color:#222}
|
||||
table{width:100%;border-collapse:collapse;margin:10px 0}
|
||||
th,td{border:1px solid #ccc;padding:6px;text-align:left}
|
||||
th{background:#263238;color:#fff}
|
||||
.bar{display:flex;justify-content:space-between;align-items:center;background:#263238;color:#fff;padding:10px;margin-bottom:15px}
|
||||
.bar a{color:#80cbc4}
|
||||
</style></head><body>
|
||||
<div class="bar">
|
||||
<span><strong>📋 Записи</strong> <%= company.client_id %> — <%= company.name || company.client_id %></span>
|
||||
<span><a href="/v2/admin">← Админка</a></span>
|
||||
</div>
|
||||
<p>Записей: <strong><%= used %></strong> из <%= limit %> <%= includeDeleted ? '(с удалёнными: ' + entries.length + ')' : '' %></p>
|
||||
<table>
|
||||
<tr><th>CIDR</th><th>Комментарий</th><th>Кто</th><th>Когда</th><th>Статус</th></tr>
|
||||
<% if (entries.length === 0) { %><tr><td colspan="5">Нет записей</td></tr><% } %>
|
||||
<% entries.forEach(function(e) { %>
|
||||
<tr style="<%= e.deleted_at ? 'text-decoration:line-through;opacity:0.5' : '' %>">
|
||||
<td><%= e.value_cidr %></td>
|
||||
<td><%= e.comment || '' %></td>
|
||||
<td><%= e.created_by %></td>
|
||||
<td><%= new Date(e.created_at).toLocaleString('ru') %></td>
|
||||
<td><%= e.deleted_at ? 'удалено' : 'активна' %></td>
|
||||
</tr>
|
||||
<% }) %>
|
||||
</table>
|
||||
<p><a href="?companyId=<%= company.id %>&deleted=<%= includeDeleted ? '0' : '1' %>"><%= includeDeleted ? 'Скрыть удалённые' : 'Показать удалённые' %></a></p>
|
||||
</body></html>
|
||||
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8"><title>Admin — IP WhiteList v<%= version %></title>
|
||||
<style>
|
||||
body{font-family:sans-serif;max-width:1100px;margin:20px auto;color:#222}
|
||||
table{width:100%;border-collapse:collapse;margin:10px 0}
|
||||
th,td{border:1px solid #ccc;padding:6px;text-align:left}
|
||||
th{background:#263238;color:#fff}
|
||||
.bar{display:flex;justify-content:space-between;align-items:center;background:#263238;color:#fff;padding:10px;margin-bottom:15px}
|
||||
.bar a{color:#80cbc4}
|
||||
button,input,select{padding:4px 8px}
|
||||
.msg{background:#4caf50;color:#fff;padding:8px;margin-bottom:10px}
|
||||
.err{background:#f44336;color:#fff;padding:8px;margin-bottom:10px}
|
||||
</style></head><body>
|
||||
<div class="bar">
|
||||
<span><strong>🛡️ ADMIN</strong> v<%= version %></span>
|
||||
<span><%= user.email || '—' %> | <a href="/v2/app">← Пользовательский</a> | <a href="/v2/logout">Выйти</a></span>
|
||||
</div>
|
||||
<script>
|
||||
const p=new URLSearchParams(location.search);
|
||||
if(p.get('msg')){document.write('<div class="msg">'+p.get('msg')+'</div>');history.replaceState(null,'','/v2/admin');}
|
||||
if(p.get('error')){document.write('<div class="err">'+p.get('error')+'</div>');history.replaceState(null,'','/v2/admin');}
|
||||
</script>
|
||||
<h2>Компании (<%= companies.length %>)</h2>
|
||||
<table>
|
||||
<tr><th>Компания</th><th>Client ID</th><th>Записей</th><th>Лимит</th><th></th><th>Новый лимит</th></tr>
|
||||
<% if (companies.length === 0) { %><tr><td colspan="6">Нет компаний</td></tr><% } %>
|
||||
<% companies.forEach(function(c) { %>
|
||||
<tr>
|
||||
<td><%= c.name || c.client_id %></td>
|
||||
<td><code><%= c.client_id %></code></td>
|
||||
<td><strong><%= c.active_count %></strong> / <%= c.custom_limit != null ? c.custom_limit : 15 %></td>
|
||||
<td><%= c.custom_limit != null ? c.custom_limit : '—' %></td>
|
||||
<td>
|
||||
<a href="/v2/admin/audit?companyId=<%= c.id %>">аудит</a> |
|
||||
<a href="/v2/admin/entries?companyId=<%= c.id %>">записи</a>
|
||||
</td>
|
||||
<td>
|
||||
<form method="POST" action="/v2/admin/limit" style="display:inline">
|
||||
<input type="hidden" name="companyId" value="<%= c.id %>">
|
||||
<input name="limit" value="<%= c.custom_limit || 15 %>" size="3">
|
||||
<button>установить</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<% }) %>
|
||||
</table>
|
||||
</body></html>
|
||||
@@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8"><title>V2 IP WhiteList</title>
|
||||
<style>
|
||||
body{font-family:sans-serif;max-width:960px;margin:20px auto;color:#222}
|
||||
table{width:100%;border-collapse:collapse;margin:10px 0}
|
||||
th,td{border:1px solid #ccc;padding:6px;text-align:left}
|
||||
th{background:#f5f5f5}
|
||||
.bar{display:flex;justify-content:space-between;align-items:center;background:#eee;padding:10px;margin-bottom:10px}
|
||||
button,input,select{padding:4px 8px}
|
||||
.add-form{background:#f0f8ff;padding:10px;margin:10px 0}
|
||||
</style></head><body>
|
||||
<div class="bar">
|
||||
<span><strong>V2 IP WhiteList</strong> <small>v<%= version %></small></span>
|
||||
<span><%= user.email %> <% if (user.isAdmin) { %>| <a href="/v2/admin">ADMIN</a><% } %></span>
|
||||
<span>
|
||||
<form method="GET" action="/v2/app" style="display:inline">
|
||||
<select name="switchTo" onchange="this.form.submit()">
|
||||
<% companies.forEach(function(c) { %>
|
||||
<option value="<%= c.client_id %>" <%= c.client_id === activeClientId ? 'selected' : '' %>><%= c.company_name || c.client_id %> (<%= c.client_id %>)</option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</form>
|
||||
<a href="/v2/logout">Выйти</a>
|
||||
</span>
|
||||
</div>
|
||||
<script>
|
||||
const p=new URLSearchParams(location.search);
|
||||
if(p.get('msg')){document.body.insertAdjacentHTML('afterbegin','<div style="background:#4caf50;color:#fff;padding:8px">'+p.get('msg')+'</div>');history.replaceState(null,'','/v2/app')}
|
||||
if(p.get('error')){document.body.insertAdjacentHTML('afterbegin','<div style="background:#f44336;color:#fff;padding:8px">'+p.get('error')+'</div>');history.replaceState(null,'','/v2/app')}
|
||||
</script>
|
||||
<p>Записей: <strong><%= used %></strong> из <%= limit %></p>
|
||||
<div class="add-form">
|
||||
<form method="POST" action="/v2/app/add">
|
||||
<input name="cidr" placeholder="x.x.x.x/xx" size="18" required>
|
||||
<input name="comment" placeholder="комментарий" size="30">
|
||||
<button>Добавить</button>
|
||||
</form>
|
||||
</div>
|
||||
<table>
|
||||
<tr><th>CIDR</th><th>Комментарий</th><th>Кто</th><th>Когда</th><th></th></tr>
|
||||
<% if (entries.length === 0) { %>
|
||||
<tr><td colspan="5">Нет записей</td></tr>
|
||||
<% } %>
|
||||
<% entries.forEach(function(e) { %>
|
||||
<tr style="<%= e.deleted_at ? 'text-decoration:line-through;opacity:0.5' : '' %>">
|
||||
<td><%= e.value_cidr %></td>
|
||||
<td><%= e.comment || '' %></td>
|
||||
<td><%= e.created_by %></td>
|
||||
<td><%= new Date(e.created_at).toLocaleString('ru') %></td>
|
||||
<td>
|
||||
<% if (e.deleted_at) { %>
|
||||
<span style="color:#888">удалено</span>
|
||||
<% } else { %>
|
||||
<form method="POST" action="/v2/app/edit/<%= e.id %>" style="display:inline">
|
||||
<input name="cidr" value="<%= e.value_cidr %>" size="18">
|
||||
<input name="comment" value="<%= e.comment || '' %>" size="20">
|
||||
<button>изменить</button>
|
||||
</form>
|
||||
<form method="POST" action="/v2/app/delete/<%= e.id %>" style="display:inline">
|
||||
<button onclick="return confirm('Удалить?')">удалить</button>
|
||||
</form>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% }) %>
|
||||
</table>
|
||||
<p><a href="/v2/app?deleted=<%= includeDeleted ? '0' : '1' %>"><%= includeDeleted ? 'Скрыть удалённые' : 'Показать удалённые' %></a></p>
|
||||
</body></html>
|
||||
Reference in New Issue
Block a user