feat: admin can create users from /admin/users page

Adds a dialog form on the users list. Validates email uniqueness,
password length. Creates user as active with confirmed email.
System role can assign admin role; admin role can only create users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mguschin
2026-05-13 20:58:00 +03:00
parent 8549e98f8d
commit 52825f70de
2 changed files with 123 additions and 1 deletions

View File

@@ -4,9 +4,62 @@
{% block content %}
<div class="d-flex justify-between align-center mb-3">
<h1 style="font-size:1.3rem; margin:0;"><i class="bi bi-people me-2"></i>Пользователи</h1>
<span class="text-muted small">Всего: {{ total }}</span>
<button onclick="document.getElementById('create-user-dialog').showModal()" class="sm">
<i class="bi bi-person-plus me-1"></i>Создать пользователя
</button>
</div>
<dialog id="create-user-dialog">
<article>
<header>
<button aria-label="Закрыть" rel="prev" onclick="document.getElementById('create-user-dialog').close()"></button>
<h3>Создать пользователя</h3>
</header>
<form method="post" action="/admin/users/create">
<div class="row gap-2 mb-2">
<div class="col">
<label for="cu_first_name">Имя
<input type="text" id="cu_first_name" name="first_name" required>
</label>
</div>
<div class="col">
<label for="cu_last_name">Фамилия
<input type="text" id="cu_last_name" name="last_name">
</label>
</div>
</div>
<label for="cu_email">Email
<input type="email" id="cu_email" name="email" required>
</label>
<label for="cu_phone">Телефон
<input type="tel" id="cu_phone" name="phone" placeholder="+7 (999) 999-99-99">
</label>
<label for="cu_password">Пароль
<input type="password" id="cu_password" name="password" minlength="8" required>
</label>
{% if user.role == 'system' %}
<label for="cu_role">Роль
<select id="cu_role" name="role">
<option value="user" selected>Пользователь</option>
<option value="admin">Администратор</option>
</select>
</label>
{% endif %}
<footer class="d-flex gap-2 justify-end">
<button type="button" class="outline secondary" onclick="document.getElementById('create-user-dialog').close()">Отмена</button>
<button type="submit">Создать</button>
</footer>
</form>
</article>
</dialog>
{% if create_errors %}
<div role="alert" class="alert alert-danger mb-3">
{% for e in create_errors %}<p>{{ e }}</p>{% endfor %}
</div>
<script>document.addEventListener('DOMContentLoaded', () => document.getElementById('create-user-dialog').showModal());</script>
{% endif %}
<article class="card mb-3">
<div class="card-body">
<form method="get" action="/admin/users" class="d-flex gap-2 flex-wrap align-center">