"use strict"; async function pushSmsConsent(customerId) { const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Kiosk/PushSmsConsent?customerId=${customerId}`, { method: 'POST', headers: { 'RequestVerificationToken': tok } }); const data = await res.json(); if (data.success) { toastr.success('Consent form sent to the kiosk tablet — hand it to the customer.', 'Sent to Kiosk'); document.getElementById('btnGetSmsConsent')?.classList.add('d-none'); document.getElementById('btnCancelSmsConsent')?.classList.remove('d-none'); } else { toastr.warning(data.message || 'Could not send consent to kiosk.'); } } catch { toastr.error('An error occurred. Please try again.'); } } async function cancelSmsConsent() { const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch('/Kiosk/CancelSmsConsent', { method: 'POST', headers: { 'RequestVerificationToken': tok } }); const data = await res.json(); if (data.success) { toastr.info('Consent request cancelled — kiosk is free.'); document.getElementById('btnCancelSmsConsent')?.classList.add('d-none'); document.getElementById('btnGetSmsConsent')?.classList.remove('d-none'); } } catch { toastr.error('An error occurred. Please try again.'); } } // ── Customer Notes ──────────────────────────────────────────────────────────── async function addCustomerNote(customerId) { const textarea = document.getElementById('newNoteText'); const importantCb = document.getElementById('newNoteImportant'); const note = textarea?.value?.trim(); if (!note) { toastr.warning('Please enter a note.'); return; } const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Customers/AddCustomerNote/${customerId}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': tok }, body: `note=${encodeURIComponent(note)}&isImportant=${importantCb?.checked ?? false}` }); const data = await res.json(); if (data.success) { const list = document.getElementById('customer-notes-list'); const placeholder = document.getElementById('no-notes-placeholder'); if (placeholder) placeholder.remove(); list.insertAdjacentHTML('afterbegin', data.noteHtml); textarea.value = ''; if (importantCb) importantCb.checked = false; toastr.success('Note added.'); } else { toastr.error(data.message || 'Could not add note.'); } } catch { toastr.error('An error occurred. Please try again.'); } } async function deleteCustomerNote(customerId, noteId) { const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Customers/DeleteCustomerNote/${customerId}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': tok }, body: `noteId=${noteId}` }); const data = await res.json(); if (data.success) { document.querySelector(`[data-note-id="${noteId}"]`)?.remove(); const list = document.getElementById('customer-notes-list'); if (list && list.querySelectorAll('.customer-note-item').length === 0) list.insertAdjacentHTML('afterbegin', '
No notes yet.
'); } else { toastr.error(data.message || 'Could not delete note.'); } } catch { toastr.error('An error occurred. Please try again.'); } } // ── Preferred Powders ───────────────────────────────────────────────────────── let _powderSearchTimer = null; function searchInventoryItems(term) { clearTimeout(_powderSearchTimer); const dropdown = document.getElementById('powderSearchResults'); if (!term || term.length < 2) { if (dropdown) dropdown.innerHTML = ''; return; } _powderSearchTimer = setTimeout(async () => { try { const res = await fetch(`/Customers/SearchInventoryItems?term=${encodeURIComponent(term)}`); const data = await res.json(); if (!dropdown) return; dropdown.innerHTML = data.length === 0 ? '' : data.map(i => ``).join(''); } catch { /* silent */ } }, 300); } function selectPowder(itemId, label) { document.getElementById('selectedPowderId').value = itemId; document.getElementById('powderSearchInput').value = label; const dropdown = document.getElementById('powderSearchResults'); if (dropdown) dropdown.innerHTML = ''; } async function addPreferredPowder(customerId) { const itemId = document.getElementById('selectedPowderId')?.value; const notes = document.getElementById('powderNotes')?.value?.trim() ?? ''; if (!itemId) { toastr.warning('Please search for and select a powder first.'); return; } const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Customers/AddPreferredPowder/${customerId}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': tok }, body: `inventoryItemId=${itemId}¬es=${encodeURIComponent(notes)}` }); const data = await res.json(); if (data.success) { const list = document.getElementById('preferred-powders-list'); const placeholder = document.getElementById('no-powders-placeholder'); if (placeholder) placeholder.remove(); const notesHtml = data.notes ? `
${data.notes}
` : ''; list.insertAdjacentHTML('beforeend', `
${data.itemName}${notesHtml}
`); document.getElementById('powderSearchInput').value = ''; document.getElementById('selectedPowderId').value = ''; if (document.getElementById('powderNotes')) document.getElementById('powderNotes').value = ''; toastr.success(`${data.itemName} added to preferred powders.`); } else { toastr.warning(data.message || 'Could not add powder.'); } } catch { toastr.error('An error occurred. Please try again.'); } } async function removePreferredPowder(customerId, itemId) { const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Customers/RemovePreferredPowder/${customerId}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': tok }, body: `itemId=${itemId}` }); const data = await res.json(); if (data.success) { document.querySelector(`[data-powder-id="${itemId}"]`)?.remove(); const list = document.getElementById('preferred-powders-list'); if (list && list.querySelectorAll('[data-powder-id]').length === 0) list.insertAdjacentHTML('afterbegin', '
No preferred powders yet.
'); } else { toastr.error(data.message || 'Could not remove powder.'); } } catch { toastr.error('An error occurred. Please try again.'); } } // ── Customer Contacts ────────────────────────────────────────────────────── function openAddContactModal() { document.getElementById('contactId').value = '0'; document.getElementById('contactModalTitle').textContent = 'Add Contact'; document.getElementById('contactFirstName').value = ''; document.getElementById('contactLastName').value = ''; document.getElementById('contactTitle').value = ''; document.getElementById('contactRole').value = ''; document.getElementById('contactEmail').value = ''; document.getElementById('contactPhone').value = ''; document.getElementById('contactMobilePhone').value = ''; document.getElementById('contactNotes').value = ''; document.getElementById('contactModalError').classList.add('d-none'); } async function editContact(customerId, contactId) { const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Customers/GetContact/${customerId}?contactId=${contactId}`); const data = await res.json(); if (!data.success) { toastr.error('Could not load contact.'); return; } const c = data.contact; document.getElementById('contactId').value = c.id; document.getElementById('contactModalTitle').textContent = 'Edit Contact'; document.getElementById('contactFirstName').value = c.firstName ?? ''; document.getElementById('contactLastName').value = c.lastName ?? ''; document.getElementById('contactTitle').value = c.title ?? ''; document.getElementById('contactRole').value = c.contactRole ?? ''; document.getElementById('contactEmail').value = c.email ?? ''; document.getElementById('contactPhone').value = c.phone ?? ''; document.getElementById('contactMobilePhone').value = c.mobilePhone ?? ''; document.getElementById('contactNotes').value = c.notes ?? ''; document.getElementById('contactModalError').classList.add('d-none'); new bootstrap.Modal(document.getElementById('contactModal')).show(); } catch { toastr.error('An error occurred loading the contact.'); } } async function saveContact(customerId) { const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; const contactId = parseInt(document.getElementById('contactId').value ?? '0', 10); const firstName = document.getElementById('contactFirstName').value.trim(); if (!firstName) { const err = document.getElementById('contactModalError'); err.textContent = 'First name is required.'; err.classList.remove('d-none'); return; } const params = new URLSearchParams({ FirstName: firstName, LastName: document.getElementById('contactLastName').value.trim(), Title: document.getElementById('contactTitle').value.trim(), ContactRole: document.getElementById('contactRole').value, Email: document.getElementById('contactEmail').value.trim(), Phone: document.getElementById('contactPhone').value.trim(), MobilePhone: document.getElementById('contactMobilePhone').value.trim(), Notes: document.getElementById('contactNotes').value.trim(), }); const isEdit = contactId > 0; if (isEdit) { params.append('Id', contactId); params.append('CustomerId', customerId); } const url = isEdit ? `/Customers/UpdateContact/${customerId}` : `/Customers/AddContact/${customerId}`; try { const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': tok }, body: params.toString() }); const data = await res.json(); if (data.success) { bootstrap.Modal.getInstance(document.getElementById('contactModal'))?.hide(); const tbody = document.getElementById('contacts-table-body'); const placeholder = document.getElementById('no-contacts-placeholder'); if (placeholder) placeholder.remove(); if (isEdit) { const existing = tbody.querySelector(`tr[data-contact-id="${contactId}"]`); if (existing) existing.outerHTML = data.rowHtml; else tbody.insertAdjacentHTML('beforeend', data.rowHtml); } else { tbody.insertAdjacentHTML('beforeend', data.rowHtml); } toastr.success(isEdit ? 'Contact updated.' : 'Contact added.'); } else { const err = document.getElementById('contactModalError'); err.textContent = data.message || 'An error occurred.'; err.classList.remove('d-none'); } } catch { toastr.error('An error occurred. Please try again.'); } } async function deleteContact(customerId, contactId) { if (!confirm('Delete this contact?')) return; const tok = document.querySelector('input[name="__RequestVerificationToken"]')?.value ?? ''; try { const res = await fetch(`/Customers/DeleteContact/${customerId}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': tok }, body: `contactId=${contactId}` }); const data = await res.json(); if (data.success) { document.querySelector(`tr[data-contact-id="${contactId}"]`)?.remove(); const tbody = document.getElementById('contacts-table-body'); if (tbody && tbody.querySelectorAll('tr[data-contact-id]').length === 0) tbody.insertAdjacentHTML('afterbegin', 'No additional contacts.'); toastr.success('Contact deleted.'); } else { toastr.error(data.message || 'Could not delete contact.'); } } catch { toastr.error('An error occurred. Please try again.'); } } window.updateCustomerSmsStatus = function () { const section = document.getElementById('sms-status-section'); if (!section) return; const today = new Date().toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' }); section.innerHTML = ` SMS on `; };