Files
nx9-url-shortener/templates/users.html
T

128 lines
6.9 KiB
HTML

{% extends "layout.html" %}
{% block title %}Users - BZOD{% endblock %}
{% block active_users %}active{% endblock %}
{% block header_title %}Users Management{% endblock %}
{% block content %}
{% if let Some(msg) = success %}
<div class="alert alert-success">
{{ msg }}
</div>
{% endif %}
{% if let Some(err) = error %}
<div class="alert alert-error">
{{ err }}
</div>
{% endif %}
<div class="card" style="margin-bottom: 1.5rem;">
<h2 style="margin-bottom: 1rem;">Create New User</h2>
<form action="/admin/users/create" method="POST" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem; align-items: end;">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" class="form-input" required autocomplete="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-input" required minlength="8" autocomplete="new-password">
</div>
<div class="form-group">
<label for="account_type">Account Type</label>
<select id="account_type" name="account_type" class="form-input">
<option value="standard" selected>Standard</option>
<option value="admin">Admin</option>
<option value="organization">Organization</option>
<option value="service">Service</option>
</select>
</div>
<div class="form-group" style="min-width: 100%;">
<label for="metadata">Metadata (optional)</label>
<input type="text" id="metadata" name="metadata" class="form-input" placeholder="Organization, tags, or notes">
</div>
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit" class="btn" style="grid-column: 1 / -1; width: fit-content;">Create User</button>
</form>
</div>
<div class="card" style="overflow-x: auto;">
<table>
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Status</th>
<th>Type</th>
<th>Last Login</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% if users.is_empty() %}
<tr>
<td colspan="7" style="text-align: center; color: var(--text-secondary); padding: 3rem 0;">
No users found.
</td>
</tr>
{% else %}
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<td>
<form action="/admin/users/status/{{ user.id }}" method="POST" style="display: flex; gap: 0.5rem; align-items: center;">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<select name="status" class="form-input" style="min-width: 140px;">
<option value="active" {% if user.status == "active" %}selected{% endif %}>active</option>
<option value="disabled" {% if user.status == "disabled" %}selected{% endif %}>disabled</option>
<option value="suspended" {% if user.status == "suspended" %}selected{% endif %}>suspended</option>
<option value="pending" {% if user.status == "pending" %}selected{% endif %}>pending</option>
<option value="deleted" {% if user.status == "deleted" %}selected{% endif %}>deleted</option>
</select>
<button type="submit" class="btn btn-secondary" style="padding: 0.45rem 0.75rem;">Save</button>
</form>
</td>
<td>
<form action="/admin/users/type/{{ user.id }}" method="POST" style="display: grid; gap: 0.4rem;">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<select name="account_type" class="form-input" style="min-width: 140px;">
<option value="standard" {% if user.account_type == "standard" %}selected{% endif %}>standard</option>
<option value="admin" {% if user.account_type == "admin" %}selected{% endif %}>admin</option>
<option value="organization" {% if user.account_type == "organization" %}selected{% endif %}>organization</option>
<option value="service" {% if user.account_type == "service" %}selected{% endif %}>service</option>
</select>
<button type="submit" class="btn btn-secondary" style="padding: 0.35rem 0.6rem; font-size: 0.8rem;">Save</button>
</form>
</td>
<td style="font-size: 0.85rem; color: var(--text-secondary);">
{% if let Some(login) = user.last_login %}
{{ login[0..16].replace("T", " ") }}
{% else %}
Never
{% endif %}
</td>
<td>{{ user.created_at[0..10] }}</td>
<td>
<div style="display: grid; gap: 0.5rem;">
<form action="/admin/users/password/{{ user.id }}" method="POST" style="display: grid; gap: 0.4rem;">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input type="password" name="new_password" class="form-input" placeholder="New password" minlength="8" required style="width: 190px;">
<button type="submit" class="btn btn-secondary" style="padding: 0.4rem 0.6rem; font-size: 0.8rem;">Reset</button>
</form>
<form action="/admin/users/delete/{{ user.id }}" method="POST" onsubmit="return confirm('Delete user "{{ user.username }}"? This cannot be undone.');">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit" class="btn btn-danger" style="padding: 0.4rem 0.6rem; font-size: 0.8rem;">Delete</button>
</form>
</div>
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
{% endblock %}