144 lines
6.1 KiB
HTML
144 lines
6.1 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Админы{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="flex items-center justify-between">
|
||
<div>
|
||
<h1 class="text-2xl font-semibold">Админы</h1>
|
||
<p class="mt-1 text-sm text-slate-600">Доступ к веб-панели через Telegram.</p>
|
||
</div>
|
||
</div>
|
||
|
||
{% if saved %}
|
||
<div class="mt-4 rounded-lg border border-emerald-200 bg-emerald-50 p-3 text-sm text-emerald-800">
|
||
{% if saved == 'added' %}Администратор добавлен.
|
||
{% elif saved == 'role' %}Роль обновлена.
|
||
{% elif saved == 'toggle' %}Доступ обновлён.
|
||
{% elif saved == 'deleted' %}Администратор удалён.
|
||
{% else %}Изменения сохранены.{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if errors %}
|
||
<ul class="mt-4 list-disc rounded-lg border border-red-200 bg-red-50 p-3 pl-8 text-sm text-red-700">
|
||
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
|
||
</ul>
|
||
{% endif %}
|
||
|
||
<form method="post" action="/admins" class="mt-6 rounded-lg border border-slate-200 bg-white p-4">
|
||
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
|
||
<h2 class="text-lg font-medium">Добавить администратора</h2>
|
||
<div class="mt-3 grid gap-3 sm:grid-cols-4">
|
||
<div>
|
||
<label for="telegram_id" class="text-xs text-slate-500">Telegram-ID</label>
|
||
<input
|
||
id="telegram_id"
|
||
name="telegram_id"
|
||
value="{{ form.telegram_id }}"
|
||
inputmode="numeric"
|
||
class="mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label for="username" class="text-xs text-slate-500">Username (необязательно)</label>
|
||
<input
|
||
id="username"
|
||
name="username"
|
||
value="{{ form.username }}"
|
||
placeholder="без @"
|
||
class="mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label for="role" class="text-xs text-slate-500">Роль</label>
|
||
<select
|
||
id="role"
|
||
name="role"
|
||
class="mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
>
|
||
{% for role in roles %}
|
||
<option value="{{ role }}" {% if role == form.role %}selected{% endif %}>{{ role }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div class="flex items-end">
|
||
<button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-medium text-white hover:bg-sky-700">
|
||
Добавить
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p class="mt-2 text-xs text-slate-500">
|
||
Обе роли сейчас дают полный доступ; <span class="font-mono">moderator</span> — задел на ограничения.
|
||
</p>
|
||
</form>
|
||
|
||
<div class="mt-6 overflow-x-auto rounded-lg border border-slate-200 bg-white">
|
||
<table class="min-w-full divide-y divide-slate-200 text-sm">
|
||
<thead class="bg-slate-50 text-left text-slate-600">
|
||
<tr>
|
||
<th class="px-4 py-3 font-medium">Telegram-ID</th>
|
||
<th class="px-4 py-3 font-medium">Username</th>
|
||
<th class="px-4 py-3 font-medium">Роль</th>
|
||
<th class="px-4 py-3 font-medium">Доступ</th>
|
||
<th class="px-4 py-3 font-medium">Последний вход</th>
|
||
<th class="px-4 py-3 font-medium"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="divide-y divide-slate-100">
|
||
{% for admin in admins %}
|
||
<tr class="hover:bg-slate-50">
|
||
<td class="px-4 py-3 font-mono text-xs">
|
||
{{ admin.telegram_id }}
|
||
{% if admin.telegram_id == current_id %}<span class="ml-1 text-slate-400">(вы)</span>{% endif %}
|
||
</td>
|
||
<td class="px-4 py-3">
|
||
{% if admin.username %}<span class="font-mono">@{{ admin.username }}</span>{% else %}—{% endif %}
|
||
</td>
|
||
<td class="px-4 py-3">
|
||
<form method="post" action="/admins/{{ admin.telegram_id }}/role" class="flex items-center gap-2">
|
||
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
|
||
<select
|
||
name="role"
|
||
class="rounded-lg border border-slate-300 px-2 py-1 text-sm focus:border-sky-500 focus:outline-none"
|
||
>
|
||
{% for role in roles %}
|
||
<option value="{{ role }}" {% if role == admin.role %}selected{% endif %}>{{ role }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
<button type="submit" class="text-xs text-sky-700 hover:underline">Сохранить</button>
|
||
</form>
|
||
</td>
|
||
<td class="px-4 py-3">
|
||
{% if admin.enabled %}
|
||
<span class="rounded bg-emerald-100 px-2 py-0.5 text-xs text-emerald-800">включён</span>
|
||
{% else %}
|
||
<span class="rounded bg-slate-100 px-2 py-0.5 text-xs text-slate-500">выключен</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="px-4 py-3 text-slate-600">
|
||
{{ admin.last_login_at.strftime("%d.%m.%Y %H:%M") if admin.last_login_at else "—" }}
|
||
</td>
|
||
<td class="px-4 py-3">
|
||
<div class="flex items-center justify-end gap-3">
|
||
{% if admin.telegram_id != current_id %}
|
||
<form method="post" action="/admins/{{ admin.telegram_id }}/toggle">
|
||
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
|
||
<button type="submit" class="text-slate-600 hover:underline">
|
||
{% if admin.enabled %}Выключить{% else %}Включить{% endif %}
|
||
</button>
|
||
</form>
|
||
<form method="post" action="/admins/{{ admin.telegram_id }}/delete" onsubmit="return confirm('Удалить администратора?');">
|
||
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
|
||
<button type="submit" class="text-red-600 hover:underline">Удалить</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% endblock %}
|