Files
OutFleet/vpn/templates/admin/vpn/user/change_form.html
2025-07-21 17:15:35 +03:00

220 lines
8.1 KiB
HTML

{% extends "admin/change_form.html" %}
{% load static %}
{% block content_title %}
<h1 class="h4 m-0 pr-3 mr-3 border-right">
{% if original %}
👤 User: {{ original.username }}
{% else %}
👤 Add User
{% endif %}
</h1>
{% endblock %}
{% block extrahead %}
{{ block.super }}
<style>
.user-management-section {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 0.375rem;
padding: 1rem;
margin: 0.5rem 0;
}
.user-management-section h4 {
margin: 0 0 0.75rem 0;
color: #495057;
font-size: 1rem;
font-weight: 600;
}
.server-section {
background: #ffffff;
border: 1px solid #e9ecef;
border-radius: 0.25rem;
padding: 1rem;
margin-bottom: 1rem;
}
.link-item {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 0.25rem;
padding: 0.75rem;
margin-bottom: 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.btn-sm-custom {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
border-radius: 0.2rem;
margin: 0 0.1rem;
}
.readonly .user-management-section {
border: none;
background: transparent;
padding: 0;
}
</style>
{% endblock %}
{% block admin_change_form_document_ready %}
{{ block.super }}
{% if original %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const userId = {{ original.id }};
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
// Show success/error messages in Django admin style
function showMessage(message, type = 'success') {
const messageClass = type === 'error' ? 'error' : 'success';
const messageHtml = `
<div class="alert alert-${messageClass} alert-dismissible" style="margin: 1rem 0;">
${message}
<button type="button" class="close" aria-label="Close" onclick="this.parentElement.remove()">
<span aria-hidden="true">&times;</span>
</button>
</div>
`;
const target = document.querySelector('.card-body') || document.querySelector('.content');
if (target) {
target.insertAdjacentHTML('afterbegin', messageHtml);
setTimeout(() => {
const alert = target.querySelector('.alert');
if (alert) alert.remove();
}, 5000);
}
}
// Add new link functionality
document.querySelectorAll('.add-link-btn').forEach(btn => {
btn.addEventListener('click', async function() {
const serverId = this.dataset.serverId;
const serverName = this.dataset.serverName;
const comment = prompt(`Add comment for new link on ${serverName} (optional):`, '');
if (comment === null) return;
const originalText = this.textContent;
this.textContent = '⏳ Adding...';
this.disabled = true;
try {
const response = await fetch(`/admin/vpn/user/${userId}/add-link/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrfToken
},
body: `server_id=${serverId}&comment=${encodeURIComponent(comment)}`
});
const data = await response.json();
if (data.success) {
showMessage(`✅ New link created successfully: ${data.link}`);
setTimeout(() => window.location.reload(), 1000);
} else {
showMessage(`❌ Error: ${data.error}`, 'error');
}
} catch (error) {
showMessage(`❌ Network error: ${error.message}`, 'error');
} finally {
this.textContent = originalText;
this.disabled = false;
}
});
});
// Delete link functionality
document.querySelectorAll('.delete-link-btn').forEach(btn => {
btn.addEventListener('click', async function() {
const linkId = this.dataset.linkId;
const linkName = this.dataset.linkName;
if (!confirm(`Are you sure you want to delete link ${linkName}?`)) {
return;
}
const originalText = this.textContent;
this.textContent = '⏳ Deleting...';
this.disabled = true;
try {
const response = await fetch(`/admin/vpn/user/${userId}/delete-link/${linkId}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrfToken
}
});
const data = await response.json();
if (data.success) {
showMessage(`✅ Link ${linkName} deleted successfully`);
this.closest('.link-item')?.remove();
} else {
showMessage(`❌ Error: ${data.error}`, 'error');
}
} catch (error) {
showMessage(`❌ Network error: ${error.message}`, 'error');
} finally {
this.textContent = originalText;
this.disabled = false;
}
});
});
// Add server access functionality
document.querySelectorAll('.add-server-btn').forEach(btn => {
btn.addEventListener('click', async function() {
const serverId = this.dataset.serverId;
const serverName = this.dataset.serverName;
if (!confirm(`Add access to server ${serverName}?`)) {
return;
}
const originalText = this.textContent;
this.textContent = '⏳ Adding...';
this.disabled = true;
try {
const response = await fetch(`/admin/vpn/user/${userId}/add-server-access/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrfToken
},
body: `server_id=${serverId}`
});
const data = await response.json();
if (data.success) {
showMessage(`✅ Access to ${serverName} added successfully`);
setTimeout(() => window.location.reload(), 1000);
} else {
showMessage(`❌ Error: ${data.error}`, 'error');
}
} catch (error) {
showMessage(`❌ Network error: ${error.message}`, 'error');
} finally {
this.textContent = originalText;
this.disabled = false;
}
});
});
});
</script>
{% endif %}
{% endblock %}