// 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 = ``; 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(); });