fix: show create user errors inside dialog, pre-fill form on error

Used novalidate + server-side validation so errors appear in the dialog
rather than as browser-native popups. Form fields retain submitted values.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mguschin
2026-05-13 21:01:46 +03:00
parent 52825f70de
commit fca3ca115e
2 changed files with 20 additions and 12 deletions

View File

@@ -134,7 +134,6 @@ async def admin_create_user(request: Request, db: Session = Depends(get_db)):
errors.append("Пользователь с таким email уже существует") errors.append("Пользователь с таким email уже существует")
if errors: if errors:
# Re-render list page with errors and dialog open
q = db.query(User) q = db.query(User)
total = q.count() total = q.count()
users = q.order_by(User.created_at.desc()).limit(PAGE_SIZE).all() users = q.order_by(User.created_at.desc()).limit(PAGE_SIZE).all()
@@ -148,6 +147,13 @@ async def admin_create_user(request: Request, db: Session = Depends(get_db)):
"total_pages": max(1, (total + PAGE_SIZE - 1) // PAGE_SIZE), "total_pages": max(1, (total + PAGE_SIZE - 1) // PAGE_SIZE),
"total": total, "total": total,
"create_errors": errors, "create_errors": errors,
"create_form": {
"first_name": first_name,
"last_name": last_name,
"email": email,
"phone": phone or "",
"role": role_str,
},
}) })
try: try:

View File

@@ -15,33 +15,38 @@
<button aria-label="Закрыть" rel="prev" onclick="document.getElementById('create-user-dialog').close()"></button> <button aria-label="Закрыть" rel="prev" onclick="document.getElementById('create-user-dialog').close()"></button>
<h3>Создать пользователя</h3> <h3>Создать пользователя</h3>
</header> </header>
<form method="post" action="/admin/users/create"> {% if create_errors %}
<div role="alert" class="alert alert-danger mb-3">
{% for e in create_errors %}<p>{{ e }}</p>{% endfor %}
</div>
{% endif %}
<form method="post" action="/admin/users/create" novalidate>
<div class="row gap-2 mb-2"> <div class="row gap-2 mb-2">
<div class="col"> <div class="col">
<label for="cu_first_name">Имя <label for="cu_first_name">Имя
<input type="text" id="cu_first_name" name="first_name" required> <input type="text" id="cu_first_name" name="first_name" value="{{ create_form.first_name if create_form else '' }}" required>
</label> </label>
</div> </div>
<div class="col"> <div class="col">
<label for="cu_last_name">Фамилия <label for="cu_last_name">Фамилия
<input type="text" id="cu_last_name" name="last_name"> <input type="text" id="cu_last_name" name="last_name" value="{{ create_form.last_name if create_form else '' }}">
</label> </label>
</div> </div>
</div> </div>
<label for="cu_email">Email <label for="cu_email">Email
<input type="email" id="cu_email" name="email" required> <input type="text" id="cu_email" name="email" value="{{ create_form.email if create_form else '' }}" required>
</label> </label>
<label for="cu_phone">Телефон <label for="cu_phone">Телефон
<input type="tel" id="cu_phone" name="phone" placeholder="+7 (999) 999-99-99"> <input type="tel" id="cu_phone" name="phone" value="{{ create_form.phone if create_form else '' }}" placeholder="+7 (999) 999-99-99">
</label> </label>
<label for="cu_password">Пароль <label for="cu_password">Пароль
<input type="password" id="cu_password" name="password" minlength="8" required> <input type="password" id="cu_password" name="password" required>
</label> </label>
{% if user.role == 'system' %} {% if user.role == 'system' %}
<label for="cu_role">Роль <label for="cu_role">Роль
<select id="cu_role" name="role"> <select id="cu_role" name="role">
<option value="user" selected>Пользователь</option> <option value="user" {% if not create_form or create_form.role == 'user' %}selected{% endif %}>Пользователь</option>
<option value="admin">Администратор</option> <option value="admin" {% if create_form and create_form.role == 'admin' %}selected{% endif %}>Администратор</option>
</select> </select>
</label> </label>
{% endif %} {% endif %}
@@ -54,9 +59,6 @@
</dialog> </dialog>
{% if create_errors %} {% 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> <script>document.addEventListener('DOMContentLoaded', () => document.getElementById('create-user-dialog').showModal());</script>
{% endif %} {% endif %}