Fixing disable automatic reminders, adding better visuals

This commit is contained in:
Finley Ghosh 2025-12-07 18:06:23 +11:00
parent 793b8b4a7d
commit e94cabfc3e
2 changed files with 54 additions and 68 deletions

View file

@ -710,11 +710,13 @@ func (h *QuotesHandler) DisableReminders(w http.ResponseWriter, r *http.Request)
// Parse form data
if err := r.ParseForm(); err != nil {
log.Printf("Failed to parse form for disable reminders: %v", err)
http.Error(w, "Invalid form data", http.StatusBadRequest)
return
}
quoteIDStr := r.FormValue("quote_id")
log.Printf("DisableReminders: received quote_id='%s', all form values: %v", quoteIDStr, r.Form)
if quoteIDStr == "" {
http.Error(w, "Missing quote_id", http.StatusBadRequest)
return

View file

@ -38,16 +38,16 @@
<td class="px-4 py-2 border align-middle">
{{if .LatestReminderType}}
{{if or (eq .LatestReminderType "First Reminder") (eq .LatestReminderType "First Reminder Sent")}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{else if or (eq .LatestReminderType "Second Reminder") (eq .LatestReminderType "Second Reminder Sent")}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-700 border border-yellow-200">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-700 border border-yellow-200">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{else if or (eq .LatestReminderType "Final Reminder") (eq .LatestReminderType "Final Reminder Sent")}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-red-100 text-red-700 border border-red-200">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-red-100 text-red-700 border border-red-200">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{else}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{end}}
{{else}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">No Reminder Sent</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">No Reminder Sent{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{end}}
</td>
<td class="px-4 py-2 border align-middle">
@ -137,16 +137,16 @@
<td class="px-4 py-2 border align-middle">
{{if .LatestReminderType}}
{{if or (eq .LatestReminderType "First Reminder Sent") (eq .LatestReminderType "First Reminder")}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{else if or (eq .LatestReminderType "Second Reminder Sent") (eq .LatestReminderType "Second Reminder")}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-700 border border-yellow-200">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-700 border border-yellow-200">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{else if or (eq .LatestReminderType "Final Reminder Sent") (eq .LatestReminderType "Final Reminder")}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-red-100 text-red-700 border border-red-200">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-red-100 text-red-700 border border-red-200">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{else}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">{{.LatestReminderType}}</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">{{.LatestReminderType}}{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{end}}
{{else}}
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">No Reminder Sent</span>
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">No Reminder Sent{{if .RemindersDisabled}}<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>{{end}}</span>
{{end}}
</td>
<td class="px-4 py-2 border align-middle">
@ -339,6 +339,7 @@ function hideConfirmModal() {
}
function showDisableModal(quoteID, enquiryRef) {
console.log('showDisableModal called with:', quoteID, enquiryRef);
currentQuoteID = quoteID;
document.getElementById('disableModalQuoteID').textContent = quoteID;
document.getElementById('disableModalEnquiryRef').textContent = enquiryRef;
@ -420,15 +421,18 @@ document.getElementById('modalConfirmBtn').addEventListener('click', async funct
document.getElementById('disableModalCancelBtn').addEventListener('click', hideDisableModal);
document.getElementById('disableModalConfirmBtn').addEventListener('click', async function() {
console.log('Disable confirm clicked, currentQuoteID:', currentQuoteID);
if (currentQuoteID) {
const formData = new FormData();
const formData = new URLSearchParams();
formData.append('quote_id', currentQuoteID);
console.log('FormData quote_id:', formData.get('quote_id'));
try {
const response = await fetch('/go/quotes/disable-reminders', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData
});
@ -439,14 +443,25 @@ document.getElementById('disableModalConfirmBtn').addEventListener('click', asyn
rows.forEach(row => {
const form = row.querySelector('form');
if (form && form.querySelector(`input[name="quote_id"][value="${currentQuoteID}"]`)) {
// Update reminder badge to show "Reminders Disabled"
const reminderCell = row.querySelector('td:nth-child(6)');
reminderCell.innerHTML = '<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold bg-gray-200 text-gray-700 border border-gray-300">Reminders Disabled</span>';
const enquiryRef = form.querySelector('input[name="enquiry_ref"]').value;
// Disable the action buttons
const buttonGroup = row.querySelector('.inline-flex');
if (buttonGroup) {
buttonGroup.innerHTML = '<span class="text-gray-500 text-xs">Disabled</span>';
// Update the dropdown "Disable Future Reminders" button to "Re-enable Reminders"
const dropdown = row.querySelector('div.absolute.right-0');
if (dropdown) {
const disableButton = dropdown.querySelector('button[onclick*="showDisableModal"]');
if (disableButton) {
disableButton.textContent = 'Re-enable Reminders';
disableButton.className = 'block w-full text-left px-4 py-2 hover:bg-gray-100 text-green-600';
disableButton.setAttribute('onclick', `showEnableModal('${currentQuoteID}', '${enquiryRef}')`);
}
}
// Add disabled icon to reminder badge
const reminderCell = row.querySelector('td:nth-child(6)');
const badge = reminderCell.querySelector('span');
if (badge && !badge.querySelector('.fa-ban')) {
const iconHTML = '<span class="relative group ml-1"><i class="fas fa-ban text-gray-600"></i><span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10 whitespace-nowrap">Automatic reminders disabled<span class="absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></span></span></span>';
badge.insertAdjacentHTML('beforeend', iconHTML);
}
}
});
@ -477,14 +492,15 @@ document.getElementById('enableModalCancelBtn').addEventListener('click', hideEn
document.getElementById('enableModalConfirmBtn').addEventListener('click', async function() {
if (currentQuoteID) {
const formData = new FormData();
const formData = new URLSearchParams();
formData.append('quote_id', currentQuoteID);
try {
const response = await fetch('/go/quotes/enable-reminders', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData
});
@ -495,57 +511,25 @@ document.getElementById('enableModalConfirmBtn').addEventListener('click', async
rows.forEach(row => {
const form = row.querySelector('form');
if (form && form.querySelector(`input[name="quote_id"][value="${currentQuoteID}"]`)) {
// Get the latest reminder type to show appropriate button
const reminderCell = row.querySelector('td:nth-child(6)');
const reminderText = reminderCell.textContent.trim();
// Update reminder badge back to current state (remove "Disabled")
// Keep the existing reminder type badge
// Re-enable the action buttons
const actionsCell = row.querySelector('td:nth-child(8)');
const currentReminderLevel = reminderText.includes('Final') ? 3 :
reminderText.includes('Second') ? 2 :
reminderText.includes('First') ? 1 : 0;
const enquiryRef = form.querySelector('input[name="enquiry_ref"]').value;
const customerName = form.querySelector('input[name="customer_name"]').value;
let buttonHTML = '';
if (currentReminderLevel === 0) {
buttonHTML = `<button type="button" onclick="showConfirmModal(this, 1, '${enquiryRef}', '${customerName}', 'First Reminder')" class="w-44 px-3 py-1.5 text-xs font-medium text-white bg-cmcblue rounded-l-md hover:bg-cmcblue/90 focus:z-10">Send First Reminder</button>`;
} else if (currentReminderLevel === 1) {
buttonHTML = `<button type="button" onclick="showConfirmModal(this, 2, '${enquiryRef}', '${customerName}', 'Second Reminder')" class="w-44 px-3 py-1.5 text-xs font-medium text-white bg-cmcblue rounded-l-md hover:bg-cmcblue/90 focus:z-10">Send Second Reminder</button>`;
} else {
buttonHTML = `<button type="button" onclick="showConfirmModal(this, 3, '${enquiryRef}', '${customerName}', 'Final Reminder')" class="w-44 px-3 py-1.5 text-xs font-medium text-white bg-cmcblue rounded-l-md hover:bg-cmcblue/90 focus:z-10">Send Final Reminder</button>`;
// Update the dropdown "Re-enable Reminders" button back to "Disable Future Reminders"
const dropdown = row.querySelector('div.absolute.right-0');
if (dropdown) {
const enableButton = dropdown.querySelector('button[onclick*="showEnableModal"]');
if (enableButton) {
enableButton.textContent = 'Disable Future Reminders';
enableButton.className = 'block w-full text-left px-4 py-2 hover:bg-gray-100 text-red-600';
enableButton.setAttribute('onclick', `showDisableModal('${currentQuoteID}', '${enquiryRef}')`);
}
}
const dropdownHTML = `<button type="button" onclick="toggleDropdown(this)" class="px-2 py-1.5 text-xs font-medium text-white bg-cmcblue border-l border-cmcblue/80 rounded-r-md hover:bg-cmcblue/90 focus:z-10"></button>`;
actionsCell.querySelector('form').innerHTML = `
<input type="hidden" name="quote_id" value="${currentQuoteID}">
<input type="hidden" name="customer_email" value="${form.querySelector('input[name="customer_email"]').value}">
<input type="hidden" name="user_email" value="${form.querySelector('input[name="user_email"]').value}">
<input type="hidden" name="enquiry_ref" value="${enquiryRef}">
<input type="hidden" name="customer_name" value="${customerName}">
<input type="hidden" name="date_issued" value="${form.querySelector('input[name="date_issued"]').value}">
<input type="hidden" name="valid_until" value="${form.querySelector('input[name="valid_until"]').value}">
<div class="relative inline-block">
<div class="inline-flex rounded-md shadow-sm" role="group">
${buttonHTML}
${dropdownHTML}
</div>
<div class="hidden absolute right-0 z-10 mt-1 bg-white divide-y divide-gray-100 rounded-md shadow-lg ring-1 ring-black ring-opacity-5" style="width: 200px;">
<ul class="py-1 text-xs text-gray-700">
<li><button type="button" onclick="showConfirmModal(this, 1, '${enquiryRef}', '${customerName}', 'First Reminder')" class="block w-full text-left px-4 py-2 hover:bg-gray-100">Send First Reminder</button></li>
<li><button type="button" onclick="showConfirmModal(this, 2, '${enquiryRef}', '${customerName}', 'Second Reminder')" class="block w-full text-left px-4 py-2 hover:bg-gray-100">Send Second Reminder</button></li>
<li><button type="button" onclick="showConfirmModal(this, 3, '${enquiryRef}', '${customerName}', 'Final Reminder')" class="block w-full text-left px-4 py-2 hover:bg-gray-100">Send Final Reminder</button></li>
<li class="border-t border-gray-200"></li>
<li><button type="button" onclick="showDisableModal('${currentQuoteID}', '${enquiryRef}')" class="block w-full text-left px-4 py-2 hover:bg-gray-100 text-red-600">Disable Future Reminders</button></li>
</ul>
</div>
</div>
`;
// Remove disabled icon from reminder badge
const reminderCell = row.querySelector('td:nth-child(6)');
const disabledIcon = reminderCell.querySelector('.fa-ban');
if (disabledIcon) {
disabledIcon.closest('span.relative.group').remove();
}
}
});
} else {