Files
DosVault/templates/admin_users.html
2025-09-06 13:53:44 -04:00

180 lines
8.1 KiB
HTML

{% extends "base.html" %}
{% block title %}Manage Users - DosVault{% endblock %}
{% block content %}
<div class="mb-8">
<div class="flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold mb-2">Manage Users</h1>
<p class="text-gray-400">Create and manage user accounts</p>
</div>
<button onclick="showCreateUser()" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded">
Create New User
</button>
</div>
</div>
<div class="bg-gray-800 rounded-lg border border-gray-700 overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full">
<thead class="bg-gray-700">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider">User</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider">Role</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider">Status</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider">Created</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-700">
{% for user in users %}
<tr class="hover:bg-gray-700">
<td class="px-6 py-4 whitespace-nowrap">
<div>
<p class="text-sm font-medium text-white">{{ user.username }}</p>
<p class="text-sm text-gray-400">{{ user.email }}</p>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 py-1 rounded text-xs
{% if user.role == 'super' %}bg-red-600
{% elif user.role == 'normal' %}bg-blue-600
{% else %}bg-yellow-600{% endif %}">
{{ user.role.upper() }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 py-1 rounded text-xs
{% if user.is_active %}bg-green-600{% else %}bg-gray-600{% endif %}">
{% if user.is_active %}ACTIVE{% else %}INACTIVE{% endif %}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-300">
{{ user.created_at.strftime('%Y-%m-%d') if user.created_at else 'N/A' }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm">
<div class="flex space-x-2">
{% if user.id != current_user.id %}
<button onclick="toggleUserActive({{ user.id }})"
class="{% if user.is_active %}text-red-400 hover:text-red-300{% else %}text-green-400 hover:text-green-300{% endif %}">
{% if user.is_active %}Deactivate{% else %}Activate{% endif %}
</button>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!-- Pagination -->
{% if total_pages > 1 %}
<div class="mt-8 flex justify-center">
<nav class="flex items-center space-x-2">
{% if current_page > 1 %}
<a href="?page={{ current_page - 1 }}"
class="px-3 py-2 bg-gray-700 hover:bg-gray-600 rounded text-sm">
Previous
</a>
{% endif %}
{% for page_num in range(1, total_pages + 1) %}
{% if page_num == current_page %}
<span class="px-3 py-2 bg-blue-600 rounded text-sm">{{ page_num }}</span>
{% elif page_num <= current_page + 2 and page_num >= current_page - 2 %}
<a href="?page={{ page_num }}"
class="px-3 py-2 bg-gray-700 hover:bg-gray-600 rounded text-sm">
{{ page_num }}
</a>
{% endif %}
{% endfor %}
{% if current_page < total_pages %}
<a href="?page={{ current_page + 1 }}"
class="px-3 py-2 bg-gray-700 hover:bg-gray-600 rounded text-sm">
Next
</a>
{% endif %}
</nav>
</div>
{% endif %}
<!-- Create User Modal -->
<div id="createUserModal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-gray-800 border-gray-700">
<div class="mt-3">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-medium text-white">Create New User</h3>
<button onclick="hideCreateUser()" class="text-gray-400 hover:text-white">&times;</button>
</div>
<form method="POST" class="space-y-4">
<div>
<input type="text" name="username" placeholder="Username" required
class="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<input type="email" name="email" placeholder="Email" required
class="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<input type="password" name="password" placeholder="Password" required
class="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<select name="role" required
class="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">Select Role</option>
<option value="demo">Demo User</option>
<option value="normal">Normal User</option>
<option value="super">Super User</option>
</select>
</div>
<div class="flex justify-between">
<button type="button" onclick="hideCreateUser()" class="px-4 py-2 bg-gray-600 hover:bg-gray-700 rounded-md">
Cancel
</button>
<button type="submit" class="px-4 py-2 bg-green-600 hover:bg-green-700 rounded-md">
Create User
</button>
</div>
</form>
</div>
</div>
</div>
<script>
function showCreateUser() {
document.getElementById('createUserModal').classList.remove('hidden');
}
function hideCreateUser() {
document.getElementById('createUserModal').classList.add('hidden');
}
async function toggleUserActive(userId) {
const token = localStorage.getItem('authToken');
if (!token) return;
try {
const response = await fetch(`/admin/users/${userId}/toggle-active`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
location.reload();
} else {
alert('Failed to update user status');
}
} catch (error) {
console.error('Error toggling user status:', error);
alert('Failed to update user status');
}
}
</script>
{% endblock %}