Files
raa-parser_poster/src/vk_parser_app/templates/users.html
T
2026-08-03 16:18:56 +05:00

127 lines
6.5 KiB
HTML

{% extends "base.html" %}
{% block body %}
<div class="mb-8">
<h1 class="text-3xl font-bold tracking-tight text-white flex items-center gap-3 mb-2">
<i data-lucide="users" class="text-app-primary w-8 h-8"></i>
Пользователи
</h1>
<div class="text-app-textMuted text-sm">Управление доступом к админ-панели.</div>
</div>
<div class="card overflow-hidden mb-8">
<div class="overflow-x-auto">
<table class="w-full text-left text-sm whitespace-nowrap">
<thead class="bg-app-bg border-b border-app-border">
<tr class="text-app-textMuted font-semibold tracking-wide uppercase text-xs">
<th class="px-4 py-3 w-16">ID</th>
<th class="px-4 py-3">Логин</th>
<th class="px-4 py-3">Роль</th>
<th class="px-4 py-3">Создан</th>
<th class="px-4 py-3">Статус</th>
<th class="px-4 py-3 w-32 text-right">Действия</th>
</tr>
</thead>
<tbody class="divide-y divide-app-border text-xs">
{% for u in users %}
<tr class="hover:bg-app-surfaceHover transition-colors">
<td class="px-4 py-3 font-mono text-app-textMuted">{{ u.id }}</td>
<td class="px-4 py-3 font-bold text-app-textMain">{{ u.login }}</td>
<td class="px-4 py-3">
<span class="badge badge-neutral px-2 py-0.5">{{ u.role }}</span>
</td>
<td class="px-4 py-3 text-app-textMuted">{{ u.created_at_fmt }}</td>
<td class="px-4 py-3">
{% if u.is_active %}
<span class="badge badge-success px-2 py-0.5 flex items-center gap-1.5 w-max">
<span class="w-1.5 h-1.5 rounded-full bg-app-success"></span> Активен
</span>
{% else %}
<span class="badge badge-error px-2 py-0.5 flex items-center gap-1.5 w-max">
<span class="w-1.5 h-1.5 rounded-full bg-app-error"></span> Заблокирован
</span>
{% endif %}
</td>
<td class="px-4 py-3 text-right">
{% if user.role == "admin" and user.id != u.id %}
<div class="flex items-center justify-end gap-2">
<form method="post" action="/users/{{ u.id }}/toggle" class="m-0 inline-block">
<input type="hidden" name="csrf_token" value="{{ user.csrf_token }}">
<button class="btn btn-xs {% if u.is_active %}btn-surface{% else %}btn-primary-outline{% endif %}" type="submit">
{% if u.is_active %}Блокировать{% else %}Разблокировать{% endif %}
</button>
</form>
<form method="post" action="/users/{{ u.id }}/delete" class="m-0 inline-block" onsubmit="return confirm('Точно удалить пользователя?')">
<input type="hidden" name="csrf_token" value="{{ user.csrf_token }}">
<button class="btn btn-xs text-app-error hover:bg-app-errorBg hover:text-app-error" type="submit">
Удалить
</button>
</form>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if pagination.pages > 1 %}
<div class="p-4 border-t border-app-border flex justify-center bg-app-bg/50">
<div class="tabs p-1">
<a class="btn btn-sm btn-ghost w-10 h-10 p-0 rounded-md {% if pagination.page == 1 %}pointer-events-none opacity-50{% endif %}" href="?page=1"><i data-lucide="chevrons-left" class="w-4 h-4"></i></a>
<a class="btn btn-sm btn-ghost w-10 h-10 p-0 rounded-md {% if pagination.page == 1 %}pointer-events-none opacity-50{% endif %}" href="?page={{ pagination.page - 1 }}"><i data-lucide="chevron-left" class="w-4 h-4"></i></a>
<span class="flex items-center justify-center px-4 text-sm font-medium text-app-textMuted bg-app-bg rounded-md border border-app-border mx-1">
{{ pagination.page }} из {{ pagination.pages }}
</span>
<a class="btn btn-sm btn-ghost w-10 h-10 p-0 rounded-md {% if pagination.page >= pagination.pages %}pointer-events-none opacity-50{% endif %}" href="?page={{ pagination.page + 1 }}"><i data-lucide="chevron-right" class="w-4 h-4"></i></a>
<a class="btn btn-sm btn-ghost w-10 h-10 p-0 rounded-md {% if pagination.page >= pagination.pages %}pointer-events-none opacity-50{% endif %}" href="?page={{ pagination.pages }}"><i data-lucide="chevrons-right" class="w-4 h-4"></i></a>
</div>
</div>
{% endif %}
</div>
{% if user.role == "admin" %}
<details class="card group/details">
<summary class="p-4 flex items-center justify-between cursor-pointer select-none hover:bg-app-surfaceHover transition-colors list-none">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-lg bg-app-primary/20 text-app-primary flex items-center justify-center">
<i data-lucide="user-plus" class="w-5 h-5"></i>
</div>
<span class="text-lg font-bold text-white">Добавить пользователя</span>
</div>
<i data-lucide="chevron-down" class="w-5 h-5 text-app-textMuted transition-transform group-open/details:rotate-180"></i>
</summary>
<div class="p-6 border-t border-app-border bg-app-bg/30">
<form method="post" action="/users/create" class="flex flex-col md:flex-row gap-6 items-end">
<input type="hidden" name="csrf_token" value="{{ user.csrf_token }}">
<div class="w-full">
<label class="block text-xs font-bold text-app-textMuted mb-1">Логин</label>
<input name="login" class="input w-full" required>
</div>
<div class="w-full">
<label class="block text-xs font-bold text-app-textMuted mb-1">Пароль</label>
<input name="password" type="password" class="input w-full" required minlength="10" placeholder="Минимум 10 символов">
</div>
<div class="w-full md:max-w-xs">
<label class="block text-xs font-bold text-app-textMuted mb-1">Роль</label>
<select name="role" class="select w-full">
<option value="editor">Редактор (editor)</option>
<option value="viewer">Читатель (viewer)</option>
<option value="admin">Администратор (admin)</option>
</select>
</div>
<button class="btn btn-primary" type="submit">
<i data-lucide="plus" class="w-4 h-4"></i> Создать
</button>
</form>
</div>
</details>
{% endif %}
{% endblock %}