105 lines
7.4 KiB
HTML
105 lines
7.4 KiB
HTML
{% extends "base.html" %}
|
|
{% import "components/macros.html" as ui %}
|
|
|
|
{% block title %}User Management - Stick{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="grow py-12 px-4 sm:px-6 lg:px-8 max-w-5xl mx-auto w-full">
|
|
|
|
<!-- Header -->
|
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-8 pb-6 border-b border-slate-900 gap-4">
|
|
<div>
|
|
<h1 class="text-3xl font-extrabold text-slate-100 tracking-tight">User Management</h1>
|
|
<p class="text-slate-400 text-sm mt-1">Manage system access, toggle roles, and provision credentials</p>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<a href="/auth/register" class="inline-flex items-center justify-center rounded-xl text-xs font-bold transition-all px-4 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white shadow-md shadow-emerald-500/10">
|
|
Register New User
|
|
</a>
|
|
<span class="text-xs font-semibold px-3 py-1.5 rounded-xl bg-slate-900 border border-slate-800 text-slate-300">
|
|
Total Users: {{ users.len() }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- User List -->
|
|
<div class="bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-6 shadow-xl overflow-hidden">
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300">
|
|
<thead>
|
|
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
|
<th scope="col" class="px-6 py-4">Username</th>
|
|
<th scope="col" class="px-6 py-4">Role</th>
|
|
<th scope="col" class="px-6 py-4">Created At</th>
|
|
<th scope="col" class="px-6 py-4 text-right">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-800">
|
|
{% if users.is_empty() %}
|
|
<tr>
|
|
<td colspan="4" class="px-6 py-8 text-center text-slate-500">
|
|
No registered users found.
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
{% for user_item in users %}
|
|
<tr class="hover:bg-[#1e293b]/20 transition duration-150">
|
|
<td class="px-6 py-4.5 whitespace-nowrap font-medium text-slate-200">
|
|
{{ user_item.username }}
|
|
{% if user_item.username == username %}
|
|
<span class="ml-2 text-[10px] bg-sky-500/10 text-sky-400 border border-sky-500/20 px-2 py-0.5 rounded-full font-bold">You</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="px-6 py-4.5 whitespace-nowrap">
|
|
{% if user_item.is_admin %}
|
|
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-bold bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
|
|
Administrator
|
|
</span>
|
|
{% else %}
|
|
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium bg-slate-900 text-slate-400 border border-slate-800">
|
|
Standard User
|
|
</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="px-6 py-4.5 whitespace-nowrap text-slate-400 text-xs">
|
|
{{ user_item.created_at.format("%B %d, %Y at %H:%M UTC") }}
|
|
</td>
|
|
<td class="px-6 py-4.5 whitespace-nowrap text-right text-xs font-medium">
|
|
<div class="flex items-center justify-end gap-2">
|
|
<a href="/auth/users/{{ user_item.id.unwrap().to_hex() }}/edit" class="p-2 rounded-lg bg-sky-500/10 hover:bg-sky-500/20 border border-sky-500/20 text-sky-400 transition" title="Edit User">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.83 20.013a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
|
</svg>
|
|
</a>
|
|
|
|
{% if user_item.username != username %}
|
|
<form action="/auth/users/{{ user_item.id.unwrap().to_hex() }}/delete" method="post" class="inline" onsubmit="return confirm('Are you sure you want to permanently delete user \'{{ user_item.username }}\'?');">
|
|
<button type="submit" class="p-2 rounded-lg bg-rose-500/10 hover:bg-rose-500/20 border border-rose-500/20 text-rose-400 transition" title="Delete User">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.34 9m-4.72 0-.34-9m9.03-3.03-.58 17.5A2.25 2.25 0 0 1 17.11 21H6.9a2.25 2.25 0 0 1-2.18-2.13L4.1 6.57m3.07-7.94h14.98m-14.98 0A1.75 1.75 0 0 1 7.25 1.5H16.75A1.75 1.75 0 0 1 18 3m-12 0h12" />
|
|
</svg>
|
|
</button>
|
|
</form>
|
|
{% else %}
|
|
<span class="p-2 rounded-lg opacity-30 text-slate-600 border border-slate-800 cursor-not-allowed" title="You cannot delete yourself">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.34 9m-4.72 0-.34-9m9.03-3.03-.58 17.5A2.25 2.25 0 0 1 17.11 21H6.9a2.25 2.25 0 0 1-2.18-2.13L4.1 6.57m3.07-7.94h14.98m-14.98 0A1.75 1.75 0 0 1 7.25 1.5H16.75A1.75 1.75 0 0 1 18 3m-12 0h12" />
|
|
</svg>
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-6 text-center text-sm text-slate-400">
|
|
<a href="/auth/password" class="font-medium text-sky-400 hover:underline">← Back to Account Settings</a>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|