167 lines
7.0 KiB
JavaScript
167 lines
7.0 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function () {
|
|
// Password visibility toggle
|
|
const togglePasswordButtons = document.querySelectorAll('.btn-toggle-password');
|
|
togglePasswordButtons.forEach(button => {
|
|
button.addEventListener('click', function () {
|
|
const targetInput = document.querySelector(this.dataset.target);
|
|
const icon = this.querySelector('i');
|
|
if (targetInput.type === 'password') {
|
|
targetInput.type = 'text';
|
|
icon.classList.remove('bi-eye-slash');
|
|
icon.classList.add('bi-eye');
|
|
} else {
|
|
targetInput.type = 'password';
|
|
icon.classList.remove('bi-eye');
|
|
icon.classList.add('bi-eye-slash');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Copy password to clipboard
|
|
const copyPasswordButtons = document.querySelectorAll('.btn-copy-password');
|
|
copyPasswordButtons.forEach(button => {
|
|
button.addEventListener('click', function () {
|
|
const targetInput = document.querySelector(this.dataset.target);
|
|
|
|
navigator.clipboard.writeText(targetInput.value).then(() => {
|
|
// Visual feedback
|
|
const originalIcon = 'bi-clipboard';
|
|
const successIcon = 'bi-check-lg';
|
|
const icon = this.querySelector('i');
|
|
|
|
icon.classList.remove(originalIcon);
|
|
icon.classList.add(successIcon);
|
|
|
|
setTimeout(() => {
|
|
icon.classList.remove(successIcon);
|
|
icon.classList.add(originalIcon);
|
|
}, 1500);
|
|
}).catch(err => {
|
|
console.error('Failed to copy password: ', err);
|
|
alert('Failed to copy password.');
|
|
});
|
|
});
|
|
});
|
|
|
|
// Client search filtering
|
|
const clientSearchInput = document.getElementById('client-search');
|
|
if (clientSearchInput) {
|
|
clientSearchInput.addEventListener('keyup', function () {
|
|
const searchTerm = this.value.toLowerCase();
|
|
const clientList = document.getElementById('client-list');
|
|
const clients = clientList.getElementsByTagName('tr');
|
|
|
|
for (let i = 0; i < clients.length; i++) {
|
|
const client = clients[i];
|
|
const clientId = client.getElementsByTagName('td')[0].textContent.toLowerCase();
|
|
const clientName = client.getElementsByTagName('td')[1].textContent.toLowerCase();
|
|
|
|
if (clientId.includes(searchTerm) || clientName.includes(searchTerm)) {
|
|
client.style.display = '';
|
|
} else {
|
|
client.style.display = 'none';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// AJAX for adding a new note
|
|
const addNoteForm = document.getElementById('add-note-form');
|
|
if (addNoteForm) {
|
|
addNoteForm.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(this);
|
|
const noteTextarea = this.querySelector('textarea[name="note"]');
|
|
|
|
fetch('add-note.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Create the new note element
|
|
const newNote = data.note;
|
|
const noteElement = document.createElement('div');
|
|
noteElement.classList.add('card', 'mb-2');
|
|
noteElement.innerHTML = `
|
|
<div class="card-body p-2">
|
|
<p class="card-text mb-1">"${newNote.note.replace(/\n/g, '<br>')}"</p>
|
|
<small class="text-muted">
|
|
Added by ${newNote.display_name} on ${new Date(newNote.created_at).toLocaleString()}
|
|
</small>
|
|
</div>
|
|
<div class="card-footer bg-transparent border-top-0 text-end p-1">
|
|
<a href="delete-note.php?note_id=${newNote.note_id}" class="btn btn-sm btn-outline-danger delete-note-btn" data-note-id="${newNote.note_id}"><i class="bi bi-trash"></i></a>
|
|
</div>
|
|
`;
|
|
|
|
// Add the new note to the list
|
|
const notesList = document.getElementById('notes-list');
|
|
notesList.insertBefore(noteElement, notesList.firstChild);
|
|
|
|
// Hide the "no notes" message if it's visible
|
|
const noNotesMessage = document.getElementById('no-notes-message');
|
|
if (noNotesMessage) {
|
|
noNotesMessage.classList.add('d-none');
|
|
}
|
|
|
|
// Clear the textarea
|
|
noteTextarea.value = '';
|
|
} else {
|
|
alert('Error adding note: ' + data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An unexpected error occurred.');
|
|
});
|
|
});
|
|
}
|
|
|
|
// AJAX for deleting a new note
|
|
const notesList = document.getElementById('notes-list');
|
|
if (notesList) {
|
|
notesList.addEventListener('click', function (e) {
|
|
const deleteButton = e.target.closest('.delete-note-btn');
|
|
if (deleteButton) {
|
|
e.preventDefault();
|
|
|
|
if (confirm('Are you sure you want to delete this note?')) {
|
|
const noteId = deleteButton.dataset.noteId;
|
|
|
|
const formData = new FormData();
|
|
formData.append('note_id', noteId);
|
|
|
|
fetch('delete-note.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Remove the note element from the DOM
|
|
deleteButton.closest('.card').remove();
|
|
|
|
// Show the "no notes" message if the list is empty
|
|
if (notesList.children.length === 0) {
|
|
const noNotesMessage = document.getElementById('no-notes-message');
|
|
if (noNotesMessage) {
|
|
noNotesMessage.classList.remove('d-none');
|
|
}
|
|
}
|
|
} else {
|
|
alert('Error deleting note: ' + data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An unexpected error occurred.');
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|