Initial go
This commit is contained in:
112
web/admin.html
112
web/admin.html
@@ -95,6 +95,15 @@
|
||||
background-color: #e67e22;
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-info:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
@@ -1042,6 +1051,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Change User Password Modal -->
|
||||
<div id="changePasswordModal" class="modal">
|
||||
<div class="modal-content" style="max-width: 500px;">
|
||||
<div class="modal-header">
|
||||
<h2 id="change-password-title">Change User Password</h2>
|
||||
<button class="close" onclick="closeChangePasswordModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="change-password-form">
|
||||
<div class="form-group full-width">
|
||||
<label for="change-password-username" style="font-weight: bold;">Username</label>
|
||||
<input type="text" id="change-password-username" name="username" readonly style="background-color: #f5f5f5; cursor: not-allowed;">
|
||||
</div>
|
||||
<div class="form-group full-width">
|
||||
<label for="change-password-new">New Password *</label>
|
||||
<input type="password" id="change-password-new" name="new_password" required>
|
||||
</div>
|
||||
<div class="form-group full-width">
|
||||
<label for="change-password-confirm">Confirm New Password *</label>
|
||||
<input type="password" id="change-password-confirm" name="confirm_password" required>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-primary" onclick="closeChangePasswordModal()">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn btn-warning">
|
||||
🔐 Change Password
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Success Notification -->
|
||||
<div id="notification" class="notification"></div>
|
||||
|
||||
@@ -2518,6 +2561,9 @@
|
||||
<button class="btn btn-warning btn-icon" onclick="event.stopPropagation(); openUserEditModal(${user.id})" title="Edit User">
|
||||
✏️
|
||||
</button>
|
||||
<button class="btn btn-info btn-icon" onclick="event.stopPropagation(); openChangePasswordModal(${user.id}, '${user.username}')" title="Change Password">
|
||||
🔐
|
||||
</button>
|
||||
</td>
|
||||
`;
|
||||
|
||||
@@ -2591,6 +2637,72 @@
|
||||
isNewUser = false;
|
||||
}
|
||||
|
||||
let currentChangePasswordUserId = null;
|
||||
|
||||
function openChangePasswordModal(userId, username) {
|
||||
if (!accessToken) return;
|
||||
|
||||
currentChangePasswordUserId = userId;
|
||||
document.getElementById('change-password-username').value = username;
|
||||
document.getElementById('change-password-new').value = '';
|
||||
document.getElementById('change-password-confirm').value = '';
|
||||
document.getElementById('changePasswordModal').style.display = 'block';
|
||||
|
||||
// Auto-focus on new password field
|
||||
setTimeout(() => {
|
||||
document.getElementById('change-password-new').focus();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function closeChangePasswordModal() {
|
||||
document.getElementById('changePasswordModal').style.display = 'none';
|
||||
currentChangePasswordUserId = null;
|
||||
}
|
||||
|
||||
// Change password form submission
|
||||
document.getElementById('change-password-form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!accessToken || !currentChangePasswordUserId) return;
|
||||
|
||||
const newPassword = document.getElementById('change-password-new').value.trim();
|
||||
const confirmPassword = document.getElementById('change-password-confirm').value.trim();
|
||||
|
||||
// Validate passwords match
|
||||
if (newPassword !== confirmPassword) {
|
||||
showNotification('Passwords do not match!', true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate password length
|
||||
if (newPassword.length < 6) {
|
||||
showNotification('Password must be at least 6 characters long!', true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/v1/auth/users/${currentChangePasswordUserId}/change-password`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${accessToken}`
|
||||
},
|
||||
body: JSON.stringify({ password: newPassword })
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.detail || 'Failed to change password');
|
||||
}
|
||||
|
||||
closeChangePasswordModal();
|
||||
showNotification('Password changed successfully!');
|
||||
} catch (error) {
|
||||
console.error('Error changing password:', error);
|
||||
showNotification(`Error changing password: ${error.message}`, true);
|
||||
}
|
||||
});
|
||||
|
||||
// User form submission
|
||||
document.getElementById('user-form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user