Fix icon hover colors, text alignment, and UI improvements

This commit is contained in:
Krikorios
2026-02-25 23:25:59 +02:00
parent 00fda3e045
commit fcc4352afa
46 changed files with 4011 additions and 600 deletions
+97 -79
View File
@@ -112,6 +112,12 @@
<span>Bookings</span>
</a>
</li>
<li class="nav-item">
<a href="/admin/availability.html" class="nav-link">
<i class="fas fa-clock"></i>
<span>Availability</span>
</a>
</li>
</ul>
</div>
@@ -154,7 +160,7 @@
</div>
<div class="header-right">
<button class="btn btn-primary" onclick="openAddUserModal()">
<button class="btn btn-primary" id="add-user-btn">
<i class="fas fa-user-plus"></i> Add User
</button>
@@ -223,8 +229,8 @@
<div class="roles-grid">
<div class="role-card">
<div class="role-header">
<span class="role-badge super-admin">Super Admin</span>
<span class="role-count">1 user</span>
<span class="role-badge admin">Administrator</span>
<span class="role-count" id="count-admin"> users</span>
</div>
<ul class="permissions-list">
<li><i class="fas fa-check"></i> Full system access</li>
@@ -238,7 +244,7 @@
<div class="role-card">
<div class="role-header">
<span class="role-badge editor">Editor</span>
<span class="role-count">1 user</span>
<span class="role-count" id="count-editor"> users</span>
</div>
<ul class="permissions-list">
<li><i class="fas fa-check"></i> Create/edit content</li>
@@ -248,20 +254,6 @@
<li><i class="fas fa-times"></i> Site settings</li>
</ul>
</div>
<div class="role-card">
<div class="role-header">
<span class="role-badge contributor">Contributor</span>
<span class="role-count">1 user</span>
</div>
<ul class="permissions-list">
<li><i class="fas fa-check"></i> Create content</li>
<li><i class="fas fa-times"></i> Publish content</li>
<li><i class="fas fa-check"></i> Upload media</li>
<li><i class="fas fa-times"></i> Delete content</li>
<li><i class="fas fa-times"></i> Site settings</li>
</ul>
</div>
</div>
</div>
</div>
@@ -270,48 +262,12 @@
<div class="card" style="margin-top: 2rem;">
<div class="card-header">
<h3><i class="fas fa-history"></i> Recent Activity</h3>
<a href="#" class="card-action">View All</a>
</div>
<div class="card-body">
<div class="activity-timeline">
<div class="activity-item">
<div class="activity-icon login">
<i class="fas fa-sign-in-alt"></i>
</div>
<div class="activity-content">
<p><strong>Super Admin</strong> logged in</p>
<span class="activity-time">10 minutes ago</span>
</div>
</div>
<div class="activity-item">
<div class="activity-icon edit">
<i class="fas fa-edit"></i>
</div>
<div class="activity-content">
<p><strong>Sarah Johnson</strong> edited <em>"New IT Security Features"</em></p>
<span class="activity-time">2 hours ago</span>
</div>
</div>
<div class="activity-item">
<div class="activity-icon create">
<i class="fas fa-plus"></i>
</div>
<div class="activity-content">
<p><strong>Sarah Johnson</strong> created new news article</p>
<span class="activity-time">Yesterday</span>
</div>
</div>
<div class="activity-item">
<div class="activity-icon settings">
<i class="fas fa-cog"></i>
</div>
<div class="activity-content">
<p><strong>Super Admin</strong> updated site settings</p>
<span class="activity-time">2 days ago</span>
</div>
<div class="activity-timeline" id="activity-timeline">
<div class="empty-state" style="padding: 2rem; text-align: center;">
<i class="fas fa-history" style="font-size: 2rem; opacity: 0.3; margin-bottom: 0.5rem; display:block;"></i>
<p>Activity is recorded in the server error log under <code>[MSPE_AUDIT]</code> entries.</p>
</div>
</div>
</div>
@@ -326,7 +282,7 @@
<div class="modal-container">
<div class="modal-header">
<h2 id="modal-title">Add Admin User</h2>
<button class="modal-close" onclick="closeModal()">&times;</button>
<button class="modal-close" id="user-modal-close">&times;</button>
</div>
<div class="modal-body">
<form id="user-form">
@@ -361,9 +317,8 @@
<div class="form-group">
<label>Role *</label>
<select class="form-select" name="role" required>
<option value="contributor">Contributor</option>
<option value="editor">Editor</option>
<option value="super-admin">Super Admin</option>
<option value="admin">Administrator</option>
</select>
</div>
<div class="form-group">
@@ -384,8 +339,8 @@
</form>
</div>
<div class="modal-footer">
<button class="btn btn-outline" onclick="closeModal()">Cancel</button>
<button class="btn btn-primary" onclick="saveUser()">
<button class="btn btn-outline" id="user-cancel-btn">Cancel</button>
<button class="btn btn-primary" id="user-save-btn">
<i class="fas fa-save"></i> Save User
</button>
</div>
@@ -398,7 +353,7 @@
<div class="modal-container modal-sm">
<div class="modal-header">
<h2>Change Password</h2>
<button class="modal-close" onclick="closePasswordModal()">&times;</button>
<button class="modal-close" id="password-modal-close">&times;</button>
</div>
<div class="modal-body">
<form id="password-form">
@@ -419,8 +374,8 @@
</form>
</div>
<div class="modal-footer">
<button class="btn btn-outline" onclick="closePasswordModal()">Cancel</button>
<button class="btn btn-primary" onclick="updatePassword()">
<button class="btn btn-outline" id="password-cancel-btn">Cancel</button>
<button class="btn btn-primary" id="password-save-btn">
<i class="fas fa-key"></i> Update Password
</button>
</div>
@@ -432,15 +387,49 @@
let allUsers = [];
document.addEventListener('DOMContentLoaded', function() {
setupEventListeners();
loadUsers();
});
function setupEventListeners() {
document.getElementById('add-user-btn')?.addEventListener('click', openAddUserModal);
document.getElementById('user-modal-close')?.addEventListener('click', closeModal);
document.getElementById('user-cancel-btn')?.addEventListener('click', closeModal);
document.getElementById('user-save-btn')?.addEventListener('click', saveUser);
document.getElementById('password-modal-close')?.addEventListener('click', closePasswordModal);
document.getElementById('password-cancel-btn')?.addEventListener('click', closePasswordModal);
document.getElementById('password-save-btn')?.addEventListener('click', updatePassword);
const userBackdrop = document.querySelector('#user-modal .modal-backdrop');
userBackdrop?.addEventListener('click', closeModal);
const passwordBackdrop = document.querySelector('#password-modal .modal-backdrop');
passwordBackdrop?.addEventListener('click', closePasswordModal);
const tbody = document.querySelector('tbody');
tbody?.addEventListener('click', function(event) {
const actionBtn = event.target.closest('[data-action]');
if (!actionBtn) return;
const { action, id } = actionBtn.dataset;
if (action === 'edit' && id) {
editUser(id);
} else if (action === 'password' && id) {
changePassword(id);
} else if (action === 'delete' && id) {
deleteUser(id);
}
});
}
async function loadUsers() {
try {
const response = await MSPE.API.get('users.php');
if (response && response.success) {
allUsers = response.data;
renderUsers(allUsers);
updateRoleCounts(allUsers);
} else {
document.querySelector('tbody').innerHTML = '<tr><td colspan="6" class="text-center">Failed to load users</td></tr>';
}
@@ -450,6 +439,14 @@
}
}
function updateRoleCounts(users) {
const counts = users.reduce((acc, u) => { acc[u.role] = (acc[u.role] || 0) + 1; return acc; }, {});
const adminCount = document.getElementById('count-admin');
const editorCount = document.getElementById('count-editor');
if (adminCount) adminCount.textContent = `${counts['admin'] || 0} user(s)`;
if (editorCount) editorCount.textContent = `${counts['editor'] || 0} user(s)`;
}
function renderUsers(users) {
const tbody = document.querySelector('tbody');
if (users.length === 0) {
@@ -457,36 +454,43 @@
return;
}
tbody.innerHTML = users.map(user => `
tbody.innerHTML = users.map(user => {
const safeName = MSPE.escapeHtml(user.name);
const safeUsername = MSPE.escapeHtml(user.username);
const safeEmail = MSPE.escapeHtml(user.email);
const safeRole = MSPE.escapeHtml(user.role);
const safeStatus = MSPE.escapeHtml(user.status);
const safeId = MSPE.escapeHtml(user.id);
return `
<tr>
<td>
<div class="user-info">
<img src="https://ui-avatars.com/api/?name=${encodeURIComponent(user.name)}&background=random" alt="${user.name}">
<img src="https://ui-avatars.com/api/?name=${encodeURIComponent(user.name)}&background=random" alt="${safeName}">
<div>
<span class="name">${user.name}</span>
<span class="username">${user.username}</span>
<span class="name">${safeName}</span>
<span class="username">${safeUsername}</span>
</div>
</div>
</td>
<td>${user.email}</td>
<td><span class="role-badge ${user.role}">${user.role}</span></td>
<td>${safeEmail}</td>
<td><span class="role-badge ${safeRole}">${safeRole}</span></td>
<td>${user.last_login ? MSPE.formatDate(user.last_login) : 'Never'}</td>
<td><span class="status-badge ${user.status}">${user.status}</span></td>
<td><span class="status-badge ${safeStatus}">${safeStatus}</span></td>
<td>
<div class="action-buttons">
<button class="btn btn-sm btn-outline" onclick="editUser('${user.id}')">
<button class="btn btn-sm btn-outline" data-action="edit" data-id="${safeId}">
<i class="fas fa-edit"></i>
</button>
<button class="btn btn-sm btn-outline" onclick="changePassword('${user.id}')">
<button class="btn btn-sm btn-outline" data-action="password" data-id="${safeId}">
<i class="fas fa-key"></i>
</button>
<button class="btn btn-sm btn-danger" onclick="deleteUser('${user.id}')">
<button class="btn btn-sm btn-danger" data-action="delete" data-id="${safeId}">
<i class="fas fa-trash"></i>
</button>
</div>
</td>
</tr>
`).join('');
</tr>`;
}).join('');
}
function openAddUserModal() {
@@ -552,7 +556,21 @@
const form = document.getElementById('user-form');
const formData = new FormData(form);
const id = form.dataset.id;
// Client-side password match check for new users
if (!id) {
const pw = form.querySelector('[name="password"]').value;
const cpw = form.querySelector('[name="password_confirm"]').value;
if (pw !== cpw) {
MSPE.showNotification('Passwords do not match', 'error');
return;
}
if (pw.length < 12) {
MSPE.showNotification('Password must be at least 12 characters', 'error');
return;
}
}
if (id) formData.append('id', id);
try {