refactor: extract inline CSS/JS from views into separate asset files (20+ files)
Phase A — HTML removed from PHP files: - RateLimitMiddleware.php: heredoc moved to views/errors/429.php - public/index.php: inline HTML replaced with View::error() - AuthMiddleware.php: <script> redirect replaced with <meta refresh> Phase B — Inline CSS/JS extracted from views: - CSS: landing.css (459 lines), legal.css (shared by terms+privacy) - JS: 17 new files extracted from ~20 view files - main.js (layout sidebar + notifications) - dashboard-chart.js, server-show.js, server-services.js - nginx-manager.js, database-manager.js - terminal.js, team-show.js, team-index.js - server-list.js, server-permissions.js (shared by edit+create) - server-ssl.js, server-processes.js, system-users.js - admin-users.js, audit-log.js, admin-notifications.js, admin-security.js - notifications.js Total: -3264 lines from views, +288 lines in new assets
This commit is contained in:
187
public/assets/js/team-show.js
Normal file
187
public/assets/js/team-show.js
Normal file
@@ -0,0 +1,187 @@
|
||||
function getCsrfToken() {
|
||||
return document.querySelector('meta[name="csrf-token"]')?.content || '';
|
||||
}
|
||||
|
||||
function editTeam() {
|
||||
const name = prompt('Team name:', teamName);
|
||||
if (!name) return;
|
||||
const desc = prompt('Description:', teamDescription);
|
||||
|
||||
const form = new FormData();
|
||||
form.append('name', name);
|
||||
form.append('description', desc || '');
|
||||
form.append('_csrf_token', getCsrfToken());
|
||||
|
||||
fetch('/teams/' + teamId + '/update', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() },
|
||||
body: form,
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) { showToast('success', res.message); location.reload(); }
|
||||
else { showToast('error', res.message); }
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTeam() {
|
||||
if (!confirm('Delete this team? Members will lose access to assigned servers.')) return;
|
||||
document.getElementById('postForm').action = '/teams/' + teamId + '/delete';
|
||||
document.getElementById('postForm').submit();
|
||||
}
|
||||
|
||||
let searchTimeout = null;
|
||||
let selectedUserId = null;
|
||||
|
||||
document.getElementById('addUserInput').addEventListener('input', function() {
|
||||
clearTimeout(searchTimeout);
|
||||
const q = this.value.trim();
|
||||
selectedUserId = null;
|
||||
|
||||
if (q.length < 2) {
|
||||
document.getElementById('userDropdown').classList.remove('active');
|
||||
return;
|
||||
}
|
||||
|
||||
searchTimeout = setTimeout(function() {
|
||||
fetch('/teams/search-users?q=' + encodeURIComponent(q), {
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() }
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
const dropdown = document.getElementById('userDropdown');
|
||||
dropdown.innerHTML = '';
|
||||
if (data.users && data.users.length > 0) {
|
||||
data.users.forEach(function(u) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'autocomplete-item';
|
||||
item.innerHTML = '<strong>' + escapeHtml(u.username) + '</strong> <small>' + escapeHtml(u.email) + '</small>';
|
||||
item.dataset.id = u.id;
|
||||
item.dataset.username = u.username;
|
||||
item.addEventListener('click', function() {
|
||||
selectUser(u.id, u.username);
|
||||
});
|
||||
dropdown.appendChild(item);
|
||||
});
|
||||
dropdown.classList.add('active');
|
||||
} else {
|
||||
dropdown.innerHTML = '<div class="autocomplete-empty">No users found</div>';
|
||||
dropdown.classList.add('active');
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
document.getElementById('userDropdown').classList.remove('active');
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!e.target.closest('.autocomplete')) {
|
||||
document.getElementById('userDropdown').classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
function selectUser(id, username) {
|
||||
selectedUserId = id;
|
||||
document.getElementById('addUserInput').value = username;
|
||||
document.getElementById('userDropdown').classList.remove('active');
|
||||
|
||||
const form = new FormData();
|
||||
form.append('user_id', id);
|
||||
form.append('_csrf_token', getCsrfToken());
|
||||
|
||||
fetch('/teams/' + teamId + '/add-user', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() },
|
||||
body: form,
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
showToast('success', username + ' added to team');
|
||||
location.reload();
|
||||
} else {
|
||||
showToast('error', res.message);
|
||||
document.getElementById('addUserInput').value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeMember(userId, username) {
|
||||
if (!confirm('Remove "' + username + '" from this team?')) return;
|
||||
|
||||
const form = new FormData();
|
||||
form.append('user_id', userId);
|
||||
form.append('_csrf_token', getCsrfToken());
|
||||
|
||||
fetch('/teams/' + teamId + '/remove-user', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() },
|
||||
body: form,
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) { showToast('success', res.message); location.reload(); }
|
||||
else { showToast('error', res.message); }
|
||||
});
|
||||
}
|
||||
|
||||
function addServer(e) {
|
||||
e.preventDefault();
|
||||
const serverId = document.getElementById('addServerId').value;
|
||||
const role = document.getElementById('addServerRole').value;
|
||||
if (!serverId) return;
|
||||
|
||||
const form = new FormData();
|
||||
form.append('server_id', serverId);
|
||||
form.append('role', role);
|
||||
form.append('_csrf_token', getCsrfToken());
|
||||
|
||||
fetch('/teams/' + teamId + '/add-server', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() },
|
||||
body: form,
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) { showToast('success', res.message); location.reload(); }
|
||||
else { showToast('error', res.message); }
|
||||
});
|
||||
}
|
||||
|
||||
function removeServer(serverId, name) {
|
||||
if (!confirm('Remove "' + name + '" from this team?')) return;
|
||||
|
||||
const form = new FormData();
|
||||
form.append('server_id', serverId);
|
||||
form.append('_csrf_token', getCsrfToken());
|
||||
|
||||
fetch('/teams/' + teamId + '/remove-server', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() },
|
||||
body: form,
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) { showToast('success', res.message); location.reload(); }
|
||||
else { showToast('error', res.message); }
|
||||
});
|
||||
}
|
||||
|
||||
function updateServerRole(serverId, role) {
|
||||
const form = new FormData();
|
||||
form.append('server_id', serverId);
|
||||
form.append('role', role);
|
||||
form.append('_csrf_token', getCsrfToken());
|
||||
|
||||
fetch('/teams/' + teamId + '/update-server-role', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': getCsrfToken() },
|
||||
body: form,
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) { showToast('success', 'Role updated to ' + role); }
|
||||
else { showToast('error', res.message); }
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user