va-tracker-middleware/public/js/pages/manage-tips.js

249 lines
9.2 KiB
JavaScript

// API base URL
const API_BASE = '/api/v1/client';
function openTipModal() {
const modal = document.getElementById('tipModal');
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
// Clear form
document.getElementById('tipForm').reset();
clearErrorMessages();
}
function closeTipModal() {
const modal = document.getElementById('tipModal');
modal.style.display = 'none';
document.body.style.overflow = 'auto';
// Clear form and errors
document.getElementById('tipForm').reset();
clearErrorMessages();
}
function clearErrorMessages() {
document.getElementById('vaForTipError').textContent = '';
document.getElementById('vaTipAmountError').textContent = '';
document.getElementById('vaTipDescriptionError').textContent = '';
}
document.addEventListener('DOMContentLoaded', function () {
// Mobile menu toggle
const menuToggle = document.querySelector('.mobile-menu-button');
const sidebar = document.querySelector('.dashboard-sidebar');
menuToggle.addEventListener('click', () => {
sidebar.classList.toggle('active');
});
document.getElementById('tipVaAddBtn').addEventListener('click', openTipModal);
document.getElementById('tipModal').addEventListener('click', function (e) {
if (e.target === this) {
closeTipModal();
}
});
// Close modal with escape key
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
closeLogoutModal();
closeTipModal();
}
});
document.getElementById('logoutModal').addEventListener('click', function (e) {
if (e.target === this) {
closeLogoutModal();
}
});
// Logout button - opens confirmation modal instead of directly logging out
document.getElementById('logoutButton').addEventListener('click', openLogoutModal);
// Confirm logout button
document.getElementById('confirmLogoutBtn').addEventListener('click', handleLogout);
});
// ------------------------------
// TIP FORM SUBMISSION HANDLER
// ------------------------------
document.getElementById('tipForm').addEventListener('submit', async function (e) {
e.preventDefault();
// clearErrorMessages();
const vaId = document.getElementById('vaForTip').value;
const amount = document.getElementById('vaTipAmount').value.trim();
const description = document.getElementById('vaTipDescription').value.trim();
let isValid = true;
// Validation
if (!vaId) {
document.getElementById('vaForTipError').textContent = "Please select a virtual assistant.";
isValid = false;
}
if (!amount || isNaN(amount) || Number(amount) <= 0) {
document.getElementById('vaTipAmountError').textContent = "Enter a valid tip amount.";
isValid = false;
}
if (!isValid) return;
// Prepare API body
const payload = {
vaId,
amount: Number(amount),
description
};
try {
document.getElementById('submitTipBtn').disabled = true;
document.getElementById('submitTipBtn').textContent = "Submitting...";
const response = await fetchWithAuth(`/api/v1/client/tips`, {
method: "POST",
body: JSON.stringify(payload)
});
const data = await response.json();
if (!response.ok) {
alert(data.message || "Failed to submit tip.");
return;
}
alert("Tip submitted successfully!");
closeTipModal();
// Optionally refresh page or reload tips list
window.location.reload();
} catch (err) {
console.error("Tip submit error:", err);
alert("Something went wrong while submitting tip.");
} finally {
document.getElementById('submitTipBtn').disabled = false;
document.getElementById('submitTipBtn').textContent = "Submit Tip";
}
});
document.addEventListener('DOMContentLoaded', function () {
// Load VAs for tip selection
async function loadVAs() {
try {
const response = await fetchWithAuth(`${API_BASE}/dashboard`);
const data = await response.json();
if (!response.ok) {
console.error("Failed to load VAs:", data.message);
return;
}
const vaSelect = document.getElementById('vaForTip');
data.data.allVAs.forEach(va => {
const option = document.createElement('option');
option.value = va.id;
option.textContent = va.name;
vaSelect.appendChild(option);
});
} catch (error) {
console.error("Error loading VAs:", error);
}
}
loadVAs();
});
document.addEventListener('DOMContentLoaded', function () {
// Load VAs for tip selection
async function loadTips() {
try {
const response = await fetchWithAuth(`${API_BASE}/tips`);
if (!response.ok) {
console.error("Failed to load VAs:", data.message);
return;
}
const data = await response.json();
const vaSelect = document.getElementById('vaTipTableBody');
data.data.forEach(tip => {
const row = document.createElement('tr');
const cellVoid = document.createElement('td');
const cellStatus = document.createElement('td');
const cellName = document.createElement('td');
const cellDescription = document.createElement('td');
const cellDate = document.createElement('td');
const cellAmount = document.createElement('td');
cellVoid.innerHTML = `<button id='voidBtn' class='void-btn-a' data-id='${tip._id}'>Void</button>`;
cellVoid.classList.add('void-btn');
cellStatus.textContent = tip.status;
cellName.textContent = tip.vaName;
cellDescription.textContent = tip.description;
cellDate.textContent = tip.createdAt ? new Date(tip.createdAt).toLocaleDateString() : '';
cellAmount.textContent = `$${parseFloat(tip.amount).toFixed(2)}`;
row.appendChild(cellVoid);
row.appendChild(cellStatus);
row.appendChild(cellName);
row.appendChild(cellDescription);
row.appendChild(cellDate);
row.appendChild(cellAmount);
vaSelect.appendChild(row);
});
document.querySelectorAll('.void-btn-a').forEach(button => {
button.addEventListener('click', async function () {
const tipId = this.getAttribute('data-id');
if (confirm('Are you sure you want to void this tip?')) {
try {
const response = await fetchWithAuth(`${API_BASE}/tips/${tipId}`, {
method: 'DELETE'
});
const result = await response.json();
if (!response.ok) {
alert(result.message || 'Failed to void tip.');
return;
}
alert('Tip voided successfully!');
window.location.reload();
} catch (error) {
console.error('Error voiding tip:', error);
alert('Something went wrong while voiding the tip.');
}
}
});
});
} catch (error) {
console.error("Error loading VAs:", error);
}
}
loadTips();
});