feat(admin): add Users management (list/create/reset/delete/toggle), seed test users; improve UI with modern styles
This commit is contained in:
84
templates/admin/users.html
Normal file
84
templates/admin/users.html
Normal file
@@ -0,0 +1,84 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<h3 class="me-auto">Пользователи</h3>
|
||||
<a href="{{ url_for('manage_surveys') }}" class="btn btn-outline-secondary btn-sm">К опросам</a>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Создать пользователя</h5>
|
||||
<form method="post" action="{{ url_for('manage_users') }}" class="row gy-2" onsubmit="showLoading(this)">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="username" class="form-control" placeholder="Логин" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="email" name="email" class="form-control" placeholder="Email" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="full_name" class="form-control" placeholder="ФИО (необязательно)">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="password" class="form-control" placeholder="Пароль" required>
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-center">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="is_admin" id="is_admin">
|
||||
<label class="form-check-label" for="is_admin">Админ</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button id="submitBtn" type="submit" class="btn btn-primary">Создать</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Список пользователей</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Логин</th>
|
||||
<th>ФИО</th>
|
||||
<th>Email</th>
|
||||
<th>Роль</th>
|
||||
<th style="width:320px">Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for u in users %}
|
||||
<tr>
|
||||
<td>{{ u.id }}</td>
|
||||
<td>{{ u.username }}</td>
|
||||
<td>{{ u.full_name or '—' }}</td>
|
||||
<td>{{ u.email }}</td>
|
||||
<td>
|
||||
{% if u.is_admin %}<span class="badge bg-danger">Админ</span>{% else %}<span class="badge bg-secondary">Пользователь</span>{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" action="{{ url_for('admin_reset_password', user_id=u.id) }}" class="d-inline-flex align-items-center gap-2" onsubmit="showLoading(this)">
|
||||
<input type="text" name="new_password" class="form-control form-control-sm" placeholder="Новый пароль" required>
|
||||
<button class="btn btn-sm btn-outline-primary" type="submit">Сменить пароль</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('admin_toggle_admin', user_id=u.id) }}" class="d-inline" onsubmit="return confirm('Изменить права пользователя?');">
|
||||
<button class="btn btn-sm btn-outline-warning" type="submit">Переключить роль</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('admin_delete_user', user_id=u.id) }}" class="d-inline" onsubmit="return confirm('Удалить пользователя {{ u.username }}?');">
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit" {% if u.id == current_user.id %}disabled{% endif %}>Удалить</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
@@ -50,6 +51,11 @@
|
||||
</button>
|
||||
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path.startswith('/admin/users') %} active{% endif %}" href="{{ url_for('manage_users') }}">Пользователи</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path.startswith('/quiz') %} active{% endif %}" href="{{ url_for('choose_survey') }}">Опросы</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user