Clean up file moves and update api_tokens.html

- Removed old admin.html and admin_users.html files
- Updated api_tokens.html to extend base.html
parent d1e2f31b
{% extends "base.html" %}
{% block title %}Admin Panel - VidAI{% endblock %}
{% block head %}
<style>
.container { max-width: 1200px; margin: 2rem auto; padding: 0 2rem; }
.admin-card { background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.05); margin-bottom: 2rem; }
.card-header { margin-bottom: 1.5rem; }
.card-header h3 { margin: 0; color: #1e293b; }
.btn { padding: 0.75rem 2rem; background: #667eea; color: white; border: none; border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer; text-decoration: none; display: inline-block; }
.btn:hover { background: #5a67d8; }
.btn-danger { background: #dc2626; }
.btn-danger:hover { background: #b91c1c; }
.btn-icon { padding: 0.5rem; background: none; border: none; cursor: pointer; color: #64748b; }
.btn-icon:hover { color: #374151; }
.table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
.table th, .table td { padding: 1rem; text-align: left; border-bottom: 1px solid #e5e7eb; }
.table th { background: #f8fafc; font-weight: 600; color: #374151; }
.status-active { color: #065f46; font-weight: 500; }
.status-inactive { color: #dc2626; font-weight: 500; }
.role-admin { color: #7c3aed; font-weight: 500; }
.role-user { color: #374151; }
.form-group { margin-bottom: 1.5rem; }
.form-group label { display: block; margin-bottom: 0.5rem; color: #374151; font-weight: 500; }
.form-group input, .form-group select { width: 100%; padding: 0.75rem; border: 2px solid #e5e7eb; border-radius: 8px; font-size: 1rem; }
.form-group input:focus, .form-group select:focus { outline: none; border-color: #667eea; }
.alert { padding: 0.75rem; border-radius: 8px; margin-bottom: 1rem; }
.alert-error { background: #fee2e2; color: #dc2626; border: 1px solid #fecaca; }
.alert-success { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
/* Modal Styles */
.modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); }
.modal.show { display: flex; align-items: center; justify-content: center; }
.modal-content { background-color: white; margin: 0; padding: 0; width: 90%; max-width: 600px; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); max-height: 90vh; overflow: hidden; display: flex; flex-direction: column; }
.modal-header { padding: 1rem 2rem; border-bottom: 1px solid #e5e7eb; display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; }
.modal-body { padding: 2rem; overflow-y: auto; flex: 1; }
.modal-footer { padding: 1rem 2rem; border-top: 1px solid #e5e7eb; text-align: right; flex-shrink: 0; }
.form-row { display: flex; gap: 1rem; }
.form-row .form-group { flex: 1; }
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="admin-card">
<div class="card-header">
<h3><i class="fas fa-users-cog"></i> User Management</h3>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'error' if category == 'error' else 'success' }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<table class="table">
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
<th>Tokens</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.get('username', 'N/A') }}</td>
<td>{{ user.get('email', 'N/A') }}</td>
<td><span class="role-{{ user.get('role', 'user') }}">{{ user.get('role', 'user').title() }}</span></td>
<td><span class="status-{{ 'active' if user.get('active') else 'inactive' }}">{{ 'Active' if user.get('active') else 'Inactive' }}</span></td>
<td>{{ user.get('tokens', 0) }}</td>
<td>{{ user.get('created_at', 'N/A')[:10] if user.get('created_at') else 'N/A' }}</td>
<td>
<button onclick="editUser({{ user.get('id') }}, '{{ user.get('username') }}', '{{ user.get('email') }}', '{{ user.get('role') }}', {{ user.get('tokens', 0) }}, {{ user.get('active')|lower }})" class="btn-icon" title="Edit"><i class="fas fa-edit"></i></button>
{% if user.get('active') %}
<a href="/admin/users/{{ user.get('id') }}/deactivate" class="btn-icon" title="Deactivate"><i class="fas fa-ban"></i></a>
{% else %}
<a href="/admin/users/{{ user.get('id') }}/activate" class="btn-icon" title="Activate" style="color: #059669;"><i class="fas fa-check"></i></a>
{% endif %}
<button onclick="deleteUser({{ user.get('id') }}, '{{ user.get('username') }}')" class="btn-icon" title="Delete" style="color: #dc2626;"><i class="fas fa-trash"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="admin-card">
<div class="card-header">
<h3><i class="fas fa-plus"></i> Create New User</h3>
</div>
<form method="post" action="/admin/users/create">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="role">Role</label>
<select id="role" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="form-group">
<label for="tokens">Initial Tokens</label>
<input type="number" id="tokens" name="tokens" value="0" min="0">
</div>
<button type="submit" class="btn">Create User</button>
</form>
</div>
<!-- Edit User Modal -->
<div id="editUserModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Edit User</h3>
<span onclick="closeEditModal()" style="cursor: pointer; font-size: 1.5rem;">&times;</span>
</div>
<form id="editUserForm" method="post" action="">
<div class="modal-body">
<input type="hidden" id="editUserId" name="user_id">
<div class="form-group">
<label for="editUsername">Username</label>
<input type="text" id="editUsername" name="username" required>
</div>
<div class="form-group">
<label for="editEmail">Email</label>
<input type="email" id="editEmail" name="email" required>
</div>
<div class="form-row">
<div class="form-group">
<label for="editRole">Role</label>
<select id="editRole" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="form-group">
<label for="editTokens">Tokens</label>
<input type="number" id="editTokens" name="tokens" min="0" required>
</div>
</div>
<div class="form-group">
<label for="editPassword">New Password (leave empty to keep current)</label>
<input type="password" id="editPassword" name="password">
</div>
</div>
<div class="modal-footer">
<button type="button" onclick="closeEditModal()" class="btn" style="background: #6b7280;">Cancel</button>
<button type="submit" class="btn">Update User</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit User Modal -->
<div id="editUserModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Edit User</h3>
<span onclick="closeEditModal()" style="cursor: pointer; font-size: 1.5rem;">&times;</span>
</div>
<form id="editUserForm" method="post" action="">
<div class="modal-body">
<input type="hidden" id="editUserId" name="user_id">
<div class="form-group">
<label for="editUsername">Username</label>
<input type="text" id="editUsername" name="username" required>
</div>
<div class="form-group">
<label for="editEmail">Email</label>
<input type="email" id="editEmail" name="email" required>
</div>
<div class="form-row">
<div class="form-group">
<label for="editRole">Role</label>
<select id="editRole" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="form-group">
<label for="editTokens">Tokens</label>
<input type="number" id="editTokens" name="tokens" min="0" required>
</div>
</div>
<div class="form-group">
<label for="editPassword">New Password (leave empty to keep current)</label>
<input type="password" id="editPassword" name="password">
</div>
</div>
<div class="modal-footer">
<button type="button" onclick="closeEditModal()" class="btn" style="background: #6b7280;">Cancel</button>
<button type="submit" class="btn">Update User</button>
</div>
</form>
</div>
</div>
<script>
function editUser(id, username, email, role, tokens, active) {
document.getElementById('editUserId').value = id;
document.getElementById('editUsername').value = username;
document.getElementById('editEmail').value = email;
document.getElementById('editRole').value = role;
document.getElementById('editTokens').value = tokens;
document.getElementById('editPassword').value = '';
document.getElementById('editUserForm').action = `/admin/users/${id}/update`;
document.getElementById('editUserModal').classList.add('show');
document.body.style.overflow = 'hidden';
}
function closeEditModal() {
document.getElementById('editUserModal').classList.remove('show');
document.body.style.overflow = 'auto';
}
function deleteUser(id, username) {
if (confirm(`Are you sure you want to delete user "${username}"? This action cannot be undone.`)) {
// Create a form and submit it
const form = document.createElement('form');
form.method = 'POST';
form.action = `/admin/users/${id}/delete`;
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'confirm_delete';
input.value = 'yes';
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
}
// Close modal when clicking outside
window.onclick = function(event) {
const modal = document.getElementById('editUserModal');
if (event.target == modal) {
closeEditModal();
}
}
</script>
</div>
{% endblock %}
\ No newline at end of file
{% extends "base.html" %}
{% block title %}Admin Panel - VidAI{% endblock %}
{% block head %}
<style>
.container { max-width: 1200px; margin: 2rem auto; padding: 0 2rem; }
.admin-card { background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.05); margin-bottom: 2rem; }
.card-header { margin-bottom: 1.5rem; }
.card-header h3 { margin: 0; color: #1e293b; }
.btn { padding: 0.75rem 2rem; background: #667eea; color: white; border: none; border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer; text-decoration: none; display: inline-block; }
.btn:hover { background: #5a67d8; }
.btn-danger { background: #dc2626; }
.btn-danger:hover { background: #b91c1c; }
.btn-icon { padding: 0.5rem; background: none; border: none; cursor: pointer; color: #64748b; }
.btn-icon:hover { color: #374151; }
.table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
.table th, .table td { padding: 1rem; text-align: left; border-bottom: 1px solid #e5e7eb; }
.table th { background: #f8fafc; font-weight: 600; color: #374151; }
.status-active { color: #065f46; font-weight: 500; }
.status-inactive { color: #dc2626; font-weight: 500; }
.role-admin { color: #7c3aed; font-weight: 500; }
.role-user { color: #374151; }
.form-group { margin-bottom: 1.5rem; }
.form-group label { display: block; margin-bottom: 0.5rem; color: #374151; font-weight: 500; }
.form-group input, .form-group select { width: 100%; padding: 0.75rem; border: 2px solid #e5e7eb; border-radius: 8px; font-size: 1rem; }
.form-group input:focus, .form-group select:focus { outline: none; border-color: #667eea; }
.alert { padding: 0.75rem; border-radius: 8px; margin-bottom: 1rem; }
.alert-error { background: #fee2e2; color: #dc2626; border: 1px solid #fecaca; }
.alert-success { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
/* Modal Styles */
.modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); }
.modal.show { display: flex; align-items: center; justify-content: center; }
.modal-content { background-color: white; margin: 0; padding: 0; width: 90%; max-width: 600px; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); max-height: 90vh; overflow: hidden; display: flex; flex-direction: column; }
.modal-header { padding: 1rem 2rem; border-bottom: 1px solid #e5e7eb; display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; }
.modal-body { padding: 2rem; overflow-y: auto; flex: 1; }
.modal-footer { padding: 1rem 2rem; border-top: 1px solid #e5e7eb; text-align: right; flex-shrink: 0; }
.form-row { display: flex; gap: 1rem; }
.form-row .form-group { flex: 1; }
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="admin-card">
<div class="card-header">
<h3><i class="fas fa-users-cog"></i> User Management</h3>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'error' if category == 'error' else 'success' }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<table class="table">
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
<th>Tokens</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.get('username', 'N/A') }}</td>
<td>{{ user.get('email', 'N/A') }}</td>
<td><span class="role-{{ user.get('role', 'user') }}">{{ user.get('role', 'user').title() }}</span></td>
<td><span class="status-{{ 'active' if user.get('active') else 'inactive' }}">{{ 'Active' if user.get('active') else 'Inactive' }}</span></td>
<td>{{ user.get('tokens', 0) }}</td>
<td>{{ user.get('created_at', 'N/A')[:10] if user.get('created_at') else 'N/A' }}</td>
<td>
<button onclick="editUser({{ user.get('id') }}, '{{ user.get('username') }}', '{{ user.get('email') }}', '{{ user.get('role') }}', {{ user.get('tokens', 0) }}, {{ user.get('active')|lower }})" class="btn-icon" title="Edit"><i class="fas fa-edit"></i></button>
{% if user.get('active') %}
<a href="/admin/users/{{ user.get('id') }}/deactivate" class="btn-icon" title="Deactivate"><i class="fas fa-ban"></i></a>
{% else %}
<a href="/admin/users/{{ user.get('id') }}/activate" class="btn-icon" title="Activate" style="color: #059669;"><i class="fas fa-check"></i></a>
{% endif %}
<button onclick="deleteUser({{ user.get('id') }}, '{{ user.get('username') }}')" class="btn-icon" title="Delete" style="color: #dc2626;"><i class="fas fa-trash"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="admin-card">
<div class="card-header">
<h3><i class="fas fa-plus"></i> Create New User</h3>
</div>
<form method="post" action="/admin/users/create">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="role">Role</label>
<select id="role" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="form-group">
<label for="tokens">Initial Tokens</label>
<input type="number" id="tokens" name="tokens" value="0" min="0">
</div>
<button type="submit" class="btn">Create User</button>
</form>
</div>
<!-- Edit User Modal -->
<div id="editUserModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Edit User</h3>
<span onclick="closeEditModal()" style="cursor: pointer; font-size: 1.5rem;">&times;</span>
</div>
<form id="editUserForm" method="post" action="">
<div class="modal-body">
<input type="hidden" id="editUserId" name="user_id">
<div class="form-group">
<label for="editUsername">Username</label>
<input type="text" id="editUsername" name="username" required>
</div>
<div class="form-group">
<label for="editEmail">Email</label>
<input type="email" id="editEmail" name="email" required>
</div>
<div class="form-row">
<div class="form-group">
<label for="editRole">Role</label>
<select id="editRole" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="form-group">
<label for="editTokens">Tokens</label>
<input type="number" id="editTokens" name="tokens" min="0" required>
</div>
</div>
<div class="form-group">
<label for="editPassword">New Password (leave empty to keep current)</label>
<input type="password" id="editPassword" name="password">
</div>
</div>
<div class="modal-footer">
<button type="button" onclick="closeEditModal()" class="btn" style="background: #6b7280;">Cancel</button>
<button type="submit" class="btn">Update User</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit User Modal -->
<div id="editUserModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Edit User</h3>
<span onclick="closeEditModal()" style="cursor: pointer; font-size: 1.5rem;">&times;</span>
</div>
<form id="editUserForm" method="post" action="">
<div class="modal-body">
<input type="hidden" id="editUserId" name="user_id">
<div class="form-group">
<label for="editUsername">Username</label>
<input type="text" id="editUsername" name="username" required>
</div>
<div class="form-group">
<label for="editEmail">Email</label>
<input type="email" id="editEmail" name="email" required>
</div>
<div class="form-row">
<div class="form-group">
<label for="editRole">Role</label>
<select id="editRole" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="form-group">
<label for="editTokens">Tokens</label>
<input type="number" id="editTokens" name="tokens" min="0" required>
</div>
</div>
<div class="form-group">
<label for="editPassword">New Password (leave empty to keep current)</label>
<input type="password" id="editPassword" name="password">
</div>
</div>
<div class="modal-footer">
<button type="button" onclick="closeEditModal()" class="btn" style="background: #6b7280;">Cancel</button>
<button type="submit" class="btn">Update User</button>
</div>
</form>
</div>
</div>
<script>
function editUser(id, username, email, role, tokens, active) {
document.getElementById('editUserId').value = id;
document.getElementById('editUsername').value = username;
document.getElementById('editEmail').value = email;
document.getElementById('editRole').value = role;
document.getElementById('editTokens').value = tokens;
document.getElementById('editPassword').value = '';
document.getElementById('editUserForm').action = `/admin/users/${id}/update`;
document.getElementById('editUserModal').classList.add('show');
document.body.style.overflow = 'hidden';
}
function closeEditModal() {
document.getElementById('editUserModal').classList.remove('show');
document.body.style.overflow = 'auto';
}
function deleteUser(id, username) {
if (confirm(`Are you sure you want to delete user "${username}"? This action cannot be undone.`)) {
// Create a form and submit it
const form = document.createElement('form');
form.method = 'POST';
form.action = `/admin/users/${id}/delete`;
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'confirm_delete';
input.value = 'yes';
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
}
// Close modal when clicking outside
window.onclick = function(event) {
const modal = document.getElementById('editUserModal');
if (event.target == modal) {
closeEditModal();
}
}
</script>
</div>
{% endblock %}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>API Tokens - VidAI</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
{% extends "base.html" %}
{% block title %}API Tokens - VidAI{% endblock %}
{% block head %}
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Inter', sans-serif; background: #f8fafc; }
.header { background: white; padding: 1rem 2rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment