| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- {% extends "layout.html" %}
- {% block content %}
- <div class="flex justify-between items-center mb-10">
- <div>
- <h2 class="text-4xl font-black text-white tracking-tighter italic">User Management</h2>
- <p class="text-gray-500 font-bold uppercase text-[10px] tracking-widest mt-2">Manage access and RBAC roles</p>
- </div>
- <button onclick="openAddUser()" class="bg-blue-600 hover:bg-blue-500 px-8 py-3 rounded-xl font-black shadow-2xl transition transform hover:scale-105 text-white uppercase text-xs tracking-widest">+ Create User</button>
- </div>
- <div class="bg-[#12161f] border border-gray-800 rounded-3xl overflow-hidden shadow-2xl">
- <table class="w-full text-left">
- <thead class="bg-black/20 text-[10px] font-black text-gray-500 uppercase tracking-widest border-b border-gray-800">
- <tr>
- <th class="p-6">Username</th>
- <th class="p-6">Role</th>
- <th class="p-6">Templates</th>
- <th class="p-6 text-right">Actions</th>
- </tr>
- </thead>
- <tbody class="divide-y divide-gray-800">
- {% for u, data in users.items() %}
- <tr class="hover:bg-white/[0.02] transition">
- <td class="p-6 font-bold text-white">{{ u }}</td>
- <td class="p-6">
- <span class="px-3 py-1 rounded-full text-[9px] font-black uppercase border {% if data.role=='admin' %}border-red-500/30 text-red-400 bg-red-500/10{% else %}border-blue-500/30 text-blue-400 bg-blue-500/10{% endif %}">
- {{ data.role }}
- </span>
- </td>
- <td class="p-6 text-xs text-gray-500">{{ data.assigned_templates|join(', ') or 'None' }}</td>
- <td class="p-6 text-right">
-
- <button type="button"
- onclick="editUser('{{ u|e }}', '{{ data.role|e }}', '{{ data.assigned_templates|join(',') if data.assigned_templates else '' }}')"
- class="text-blue-500 hover:text-blue-400 text-[10px] font-black uppercase mr-4">
- Edit
- </button>
- {% if u != 'admin' %}
- <a href="/users/delete/{{ u|urlencode }}" onclick="return confirm('Are you sure you want to delete this user?')" class="text-red-500 hover:text-red-400 text-[10px] font-black uppercase">Delete</a>
- {% endif %}
-
- </td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- </div>
- <div id="userModal" class="hidden fixed inset-0 bg-black/90 backdrop-blur-md flex items-center justify-center z-50 p-4">
- <div class="bg-[#12161f] border border-gray-800 w-full max-w-md rounded-3xl p-8 shadow-2xl">
- <h3 id="modalTitle" class="text-xl font-black text-white mb-6 uppercase">Add User</h3>
- <form action="/users/save" method="POST" class="space-y-4">
- <input type="hidden" name="action" id="userAction" value="add">
- <input type="hidden" name="old_username" id="oldUsername">
-
- <input type="text" name="username" id="userName" placeholder="Username" required class="w-full bg-[#0b0e14] border border-gray-800 rounded-xl p-3 text-sm font-bold text-white outline-none">
- <input type="password" name="password" id="userPass" placeholder="Password (Leave blank to keep current)" class="w-full bg-[#0b0e14] border border-gray-800 rounded-xl p-3 text-sm font-bold text-white outline-none">
-
- <select name="role" id="userRole" class="w-full bg-[#0b0e14] border border-gray-800 rounded-xl p-3 text-sm font-bold text-white outline-none">
- <option value="user">User (Restricted)</option>
- <option value="admin">Administrator</option>
- </select>
- <div class="bg-black/20 p-4 rounded-xl border border-gray-800">
- <label class="text-[10px] font-black text-gray-500 uppercase block mb-3">Assigned Templates</label>
- <div class="grid grid-cols-2 gap-2 max-h-48 overflow-y-auto pr-2">
- {% for t in all_templates %}
- <label class="flex items-center gap-2 text-xs text-gray-400 cursor-pointer hover:text-white">
- <input type="checkbox" name="assigned_templates[]" value="{{ t }}" class="template-check rounded border-gray-700 bg-gray-900 text-blue-600">
- {{ t }}
- </label>
- {% endfor %}
- </div>
- </div>
- <div class="flex gap-4 pt-4">
- <button type="button" onclick="closeUserModal()" class="flex-1 bg-gray-800 text-gray-400 font-bold py-3 rounded-xl uppercase text-xs hover:text-white transition">Cancel</button>
- <button type="submit" class="flex-1 bg-blue-600 text-white font-black py-3 rounded-xl uppercase text-xs hover:bg-blue-500 transition">Save</button>
- </div>
- </form>
- </div>
- </div>
- <script>
- function openAddUser() {
- document.getElementById('userModal').classList.remove('hidden');
- document.getElementById('userAction').value = 'add';
- document.getElementById('modalTitle').innerText = 'Add User';
- document.getElementById('userName').value = '';
- document.getElementById('userPass').value = '';
- document.getElementById('userPass').placeholder = 'Password (Required)';
- document.getElementById('userPass').required = true;
-
- var checkboxes = document.querySelectorAll('.template-check');
- for (var i = 0; i < checkboxes.length; i++) {
- checkboxes[i].checked = false;
- }
- }
- function editUser(u, role, rawTemplates) {
- // Παίρνουμε το απλό κείμενο "AWMN,LOCAL" και το κόβουμε εκεί που έχει κόμμα,
- // φτιάχνοντας μια σωστή λίστα. Αν είναι άδειο, φτιάχνουμε κενή λίστα.
- var templates = rawTemplates ? rawTemplates.split(',') : [];
- // Εμφάνιση Modal
- document.getElementById('userModal').classList.remove('hidden');
-
- // Συμπλήρωση πεδίων
- document.getElementById('userAction').value = 'edit';
- document.getElementById('oldUsername').value = u;
- document.getElementById('userName').value = u;
- document.getElementById('userRole').value = role;
- document.getElementById('modalTitle').innerText = 'Edit User';
-
- // Ο κωδικός στο Edit δεν είναι υποχρεωτικός
- document.getElementById('userPass').value = '';
- document.getElementById('userPass').placeholder = 'Password (Leave blank to keep current)';
- document.getElementById('userPass').required = false;
- // Τσεκάρισμα των σωστών Templates
- var checkboxes = document.querySelectorAll('.template-check');
- for (var i = 0; i < checkboxes.length; i++) {
- checkboxes[i].checked = templates.includes(checkboxes[i].value);
- }
- }
- function closeUserModal() {
- document.getElementById('userModal').classList.add('hidden');
- }
- </script>
- {% endblock %}
|