2025-07-13 05:50:47 -07:00
{{define "content"}}
2025-07-14 06:26:26 -07:00
< h1 class = "text-3xl font-bold mb-4 text-gray-800" > Quotes Expiring< / h1 >
2025-12-03 05:03:49 -08:00
< div class = "px-4" >
2025-07-14 06:26:26 -07:00
<!-- Expiring Soon Section -->
< h2 class = "text-xl font-semibold mt-6 mb-2" > Expiring Soon< / h2 >
2025-12-03 04:59:57 -08:00
< table class = "w-full border text-center align-middle mt-1" >
2025-07-14 06:26:26 -07:00
< thead >
< tr >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Quote< / th >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Enquiry< / th >
2025-07-17 06:35:30 -07:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Issued By< / th >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Issued At< / th >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Expires< / th >
2025-07-14 06:26:26 -07:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Reminder< / th >
2025-07-17 06:35:30 -07:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Reminder Sent< / th >
2025-12-06 21:53:59 -08:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" >
< div class = "flex items-center justify-center gap-2" >
< span > Actions< / span >
< div class = "relative group" >
< i class = "fas fa-info-circle text-blue-500 cursor-help" > < / i >
< div class = "absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-64 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10" >
Manually sent reminders will not specify the number of days until or since expiry
< div class = "absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900" > < / div >
< / div >
< / div >
< / div >
< / th >
2025-07-14 06:26:26 -07:00
< / tr >
< / thead >
< tbody >
{{range .ExpiringSoonQuotes}}
< tr class = "hover:bg-slate-50 transition" >
< td class = "px-4 py-2 border align-middle" > < a href = "/documents/view/{{.ID}}" class = "text-blue-600 underline" > {{.ID}}< / a > < / td >
2025-07-17 06:35:30 -07:00
< td class = "px-4 py-2 border align-middle" > < a href = "/enquiries/view/{{.EnquiryID}}" class = "text-blue-600 underline" > {{.EnquiryRef}}< / a > < / td >
2025-07-14 06:26:26 -07:00
< td class = "px-4 py-2 border align-middle" > {{.Username}}< / td >
2025-07-19 23:50:09 -07:00
< td class = "px-4 py-2 border align-middle" > < span class = "localdate" > {{.DateIssued}}< / span > < / td >
< td class = "px-4 py-2 border align-middle" > < span class = "localdate" > {{.ValidUntil}}< / span > < span class = "text-gray-500" > ({{.ValidUntilRelative}})< / span > < / td >
2025-07-17 06:35:30 -07:00
< 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 >
{{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 >
{{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 >
{{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 >
{{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 >
{{end}}
< / td >
< td class = "px-4 py-2 border align-middle" >
2025-07-19 23:50:09 -07:00
{{if .LatestReminderSent}}< span class = "localdatetime" > {{.LatestReminderSent}}< / span > {{else}}-{{end}}
2025-07-17 06:35:30 -07:00
< / td >
2025-12-03 04:59:57 -08:00
< td class = "px-4 py-2 border align-middle" >
< form method = "POST" action = "/go/quotes/send-reminder" style = "display:inline;" >
< input type = "hidden" name = "quote_id" value = "{{.ID}}" >
< input type = "hidden" name = "customer_email" value = "{{.CustomerEmail}}" >
< input type = "hidden" name = "user_email" value = "{{.UserEmail}}" >
< input type = "hidden" name = "enquiry_ref" value = "{{.EnquiryRef}}" >
< input type = "hidden" name = "customer_name" value = "{{.CustomerName}}" >
< input type = "hidden" name = "date_issued" value = "{{.DateIssued}}" >
< input type = "hidden" name = "valid_until" value = "{{.ValidUntil}}" >
2025-12-06 21:53:59 -08:00
{{if .RemindersDisabled}}
< button type = "button" onclick = "showEnableModal('{{.ID}}', '{{.EnquiryRef}}')" class = "px-4 py-1.5 text-xs font-medium text-white bg-green-600 rounded-md hover:bg-green-700 focus:z-10" > Re-enable Reminders< / button >
{{else}}
2025-12-06 22:35:21 -08:00
< div class = "relative inline-block" >
2025-12-06 21:53:59 -08:00
< div class = "inline-flex rounded-md shadow-sm" role = "group" >
{{if eq .LatestReminderType "No Reminder"}}
< 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 >
< 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 >
{{else if eq .LatestReminderType "First Reminder"}}
< 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 >
< 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 >
{{else if eq .LatestReminderType "Second Reminder"}}
< 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 >
< 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 >
{{else}}
< 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 >
< 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 >
{{end}}
< / div >
2025-12-06 22:35:21 -08:00
< 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;" >
2025-12-06 21:53:59 -08:00
< 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('{{.ID}}', '{{.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 >
2025-12-06 22:35:21 -08:00
< / div >
2025-12-06 21:53:59 -08:00
{{end}}
2025-12-03 04:59:57 -08:00
< / form >
< / td >
2025-07-14 06:26:26 -07:00
< / tr >
{{else}}
2025-12-03 04:59:57 -08:00
< tr > < td colspan = "8" class = "px-4 py-2 border text-center align-middle" > No quotes expiring soon.< / td > < / tr >
2025-07-14 06:26:26 -07:00
{{end}}
< / tbody >
< / table >
<!-- Recently Expired Quotes Section -->
< h2 class = "text-xl font-semibold mt-6 mb-2" > Recently Expired< / h2 >
2025-12-03 04:59:57 -08:00
< table class = "w-full border mb-6 text-center align-middle mt-1" >
2025-07-14 06:26:26 -07:00
< thead >
< tr >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Quote< / th >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Enquiry< / th >
2025-07-17 06:35:30 -07:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Issued By< / th >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Issued At< / th >
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Expires< / th >
2025-07-14 06:26:26 -07:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Reminder< / th >
2025-07-17 06:35:30 -07:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" > Reminder Sent< / th >
2025-12-06 21:53:59 -08:00
< th class = "px-4 py-3 border font-semibold text-gray-700 align-middle" >
< div class = "flex items-center justify-center gap-2" >
< span > Actions< / span >
< div class = "relative group" >
< i class = "fas fa-info-circle text-blue-500 cursor-help" > < / i >
< div class = "absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block w-64 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10" >
Manually sent reminders will not specify the number of days until or since expiry
< div class = "absolute top-full left-1/2 transform -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900" > < / div >
< / div >
< / div >
< / div >
< / th >
2025-07-14 06:26:26 -07:00
< / tr >
< / thead >
< tbody >
{{range .RecentlyExpiredQuotes}}
< tr class = "hover:bg-slate-50 transition" >
< td class = "px-4 py-2 border align-middle" > < a href = "/documents/view/{{.ID}}" class = "text-blue-600 underline" > {{.ID}}< / a > < / td >
2025-07-17 06:35:30 -07:00
< td class = "px-4 py-2 border align-middle" > < a href = "/enquiries/view/{{.EnquiryID}}" class = "text-blue-600 underline" > {{.EnquiryRef}}< / a > < / td >
2025-07-14 06:26:26 -07:00
< td class = "px-4 py-2 border align-middle" > {{.Username}}< / td >
2025-07-19 23:50:09 -07:00
< td class = "px-4 py-2 border align-middle" > < span class = "localdate" > {{.DateIssued}}< / span > < / td >
< td class = "px-4 py-2 border align-middle" > < span class = "localdate" > {{.ValidUntil}}< / span > < span class = "text-gray-500" > ({{.ValidUntilRelative}})< / span > < / td >
2025-07-17 06:35:30 -07:00
< 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 >
{{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 >
{{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 >
{{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 >
{{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 >
{{end}}
< / td >
< td class = "px-4 py-2 border align-middle" >
2025-07-19 23:50:09 -07:00
{{if .LatestReminderSent}}< span class = "localdatetime" > {{.LatestReminderSent}}< / span > {{else}}-{{end}}
2025-07-17 06:35:30 -07:00
< / td >
2025-12-03 04:59:57 -08:00
< td class = "px-4 py-2 border align-middle" >
< form method = "POST" action = "/go/quotes/send-reminder" style = "display:inline;" >
< input type = "hidden" name = "quote_id" value = "{{.ID}}" >
< input type = "hidden" name = "customer_email" value = "{{.CustomerEmail}}" >
< input type = "hidden" name = "user_email" value = "{{.UserEmail}}" >
< input type = "hidden" name = "enquiry_ref" value = "{{.EnquiryRef}}" >
< input type = "hidden" name = "customer_name" value = "{{.CustomerName}}" >
< input type = "hidden" name = "date_issued" value = "{{.DateIssued}}" >
< input type = "hidden" name = "valid_until" value = "{{.ValidUntil}}" >
2025-12-06 21:53:59 -08:00
{{if .RemindersDisabled}}
< button type = "button" onclick = "showEnableModal('{{.ID}}', '{{.EnquiryRef}}')" class = "px-4 py-1.5 text-xs font-medium text-white bg-green-600 rounded-md hover:bg-green-700 focus:z-10" > Re-enable Reminders< / button >
{{else}}
2025-12-06 22:35:21 -08:00
< div class = "relative inline-block" >
2025-12-06 21:53:59 -08:00
< div class = "inline-flex rounded-md shadow-sm" role = "group" >
{{if eq .LatestReminderType "No Reminder"}}
< 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 >
< 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 >
{{else if eq .LatestReminderType "First Reminder"}}
< 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 >
< 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 >
{{else if eq .LatestReminderType "Second Reminder"}}
< 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 >
< 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 >
{{else}}
< 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 >
< 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 >
{{end}}
< / div >
2025-12-06 22:35:21 -08:00
< 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;" >
2025-12-06 21:53:59 -08:00
< 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('{{.ID}}', '{{.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 >
2025-12-06 22:35:21 -08:00
< / div >
2025-12-06 21:53:59 -08:00
{{end}}
2025-12-03 04:59:57 -08:00
< / form >
< / td >
2025-07-14 06:26:26 -07:00
< / tr >
{{else}}
2025-12-03 04:59:57 -08:00
< tr > < td colspan = "8" class = "px-4 py-2 border text-center align-middle" > No recently expired quotes.< / td > < / tr >
2025-07-14 06:26:26 -07:00
{{end}}
< / tbody >
< / table >
< / div >
2025-12-03 04:59:57 -08:00
2025-12-06 21:53:59 -08:00
<!-- Enable Reminders Modal -->
< div id = "enableModal" class = "hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50" >
< div class = "relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white" >
< div class = "mt-3" >
< div class = "flex items-center justify-center gap-3 mb-4" >
< div class = "flex items-center justify-center w-12 h-12 bg-green-600 rounded-full flex-shrink-0" >
< i class = "fas fa-check text-white text-xl" > < / i >
< / div >
< h3 class = "text-lg leading-6 font-large font-bold text-gray-900" > Re-enable reminders?< / h3 >
< / div >
< div class = "px-7 py-3" >
< p class = "text-sm text-gray-600 text-center" >
This will allow automatic reminders to be sent again for enquiry < strong id = "enableModalEnquiryRef" > < / strong > .
< / p >
< / div >
< div class = "flex gap-3 px-4 py-3" >
< button id = "enableModalCancelBtn" class = "flex-1 px-4 py-2 bg-gray-200 text-gray-800 text-sm font-medium rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-300" >
Cancel
< / button >
< button id = "enableModalConfirmBtn" class = "flex-1 px-4 py-2 bg-green-600 text-white text-sm font-medium rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-600 focus:ring-offset-2" >
Re-enable Reminders
< / button >
< / div >
< / div >
< / div >
< / div >
2025-12-03 04:59:57 -08:00
<!-- Confirmation Modal -->
< div id = "confirmModal" class = "hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50" >
2025-12-06 21:53:59 -08:00
< div class = "relative top-20 mx-auto p-5 border w-[500px] shadow-lg rounded-md bg-white" >
2025-12-03 04:59:57 -08:00
< div class = "mt-3" >
2025-12-06 21:53:59 -08:00
< div class = "flex items-center justify-center gap-3 mb-4" >
< div class = "flex items-center justify-center w-12 h-12 bg-cmcblue rounded-full flex-shrink-0" >
< i class = "fas fa-envelope text-white text-xl" > < / i >
< / div >
< h3 class = "text-lg leading-6 font-large font-bold text-gray-900" > Are you sure?< / h3 >
2025-12-03 04:59:57 -08:00
< / div >
2025-12-03 05:03:49 -08:00
< div class = "px-7 py-3" >
2025-12-03 04:59:57 -08:00
< p class = "text-sm text-gray-600 text-center" >
Send < strong id = "modalReminderType" > < / strong > for enquiry < strong id = "modalEnquiryRef" > < / strong > to < strong id = "modalCustomerName" > < / strong > ?
< / p >
< / div >
< div class = "flex gap-3 px-4 py-3" >
< button id = "modalCancelBtn" class = "flex-1 px-4 py-2 bg-gray-200 text-gray-800 text-sm font-medium rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-300" >
Cancel
< / button >
< button id = "modalConfirmBtn" class = "flex-1 px-4 py-2 bg-cmcblue text-white text-sm font-medium rounded-md hover:bg-cmcblue/90 focus:outline-none focus:ring-2 focus:ring-cmcblue focus:ring-offset-2" >
Send Reminder
< / button >
< / div >
< / div >
< / div >
< / div >
2025-12-06 17:44:30 -08:00
<!-- Disable Reminders Modal -->
< div id = "disableModal" class = "hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50" >
2025-12-06 21:53:59 -08:00
< div class = "relative top-20 mx-auto p-5 border w-[500px] shadow-lg rounded-md bg-white" >
2025-12-06 17:44:30 -08:00
< div class = "mt-3" >
2025-12-06 21:53:59 -08:00
< div class = "flex items-center justify-center gap-3 mb-4" >
< div class = "flex items-center justify-center w-12 h-12 bg-red-600 rounded-full flex-shrink-0" >
< i class = "fas fa-ban text-white text-xl" > < / i >
< / div >
< h3 class = "text-lg leading-6 font-large font-bold text-gray-900" > Are you sure?< / h3 >
2025-12-06 17:44:30 -08:00
< / div >
< div class = "px-7 py-3" >
< p class = "text-sm text-gray-600 text-center" >
2025-12-06 21:53:59 -08:00
This will prevent future automatic reminders for quote < strong id = "disableModalQuoteID" > < / strong > in enquiry < strong id = "disableModalEnquiryRef" > < / strong > .
2025-12-06 17:44:30 -08:00
< / p >
< / div >
< div class = "flex gap-3 px-4 py-3" >
2025-12-06 21:53:59 -08:00
< button id = "disableModalCancelBtn" class = "flex-1 px-4 py-2 bg-gray-200 text-gray-800 text-sm font-medium rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-300 whitespace-nowrap" >
2025-12-06 17:44:30 -08:00
Cancel
< / button >
2025-12-06 21:53:59 -08:00
< button id = "disableModalConfirmBtn" class = "flex-1 px-4 py-2 bg-red-600 text-white text-sm font-medium rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-600 focus:ring-offset-2 whitespace-nowrap" >
2025-12-06 17:44:30 -08:00
Disable Reminders
< / button >
< / div >
< / div >
< / div >
< / div >
2025-07-19 23:50:09 -07:00
< script >
2025-12-03 04:59:57 -08:00
let currentForm = null;
let currentReminderType = null;
2025-12-06 17:44:30 -08:00
let currentQuoteID = null;
2025-12-03 04:59:57 -08:00
function showConfirmModal(button, reminderType, enquiryRef, customerName, reminderTypeName) {
currentForm = button.closest('form');
currentReminderType = reminderType;
2025-12-06 21:53:59 -08:00
// Get the current reminder type from the row
const row = button.closest('tr');
const reminderCell = row.querySelector('td:nth-child(6)');
const currentReminderText = reminderCell.textContent.trim();
// Check if trying to send same or earlier reminder than what's already been sent
const currentLevel = currentReminderText.includes('Final Reminder') ? 3 :
currentReminderText.includes('Second Reminder') ? 2 :
currentReminderText.includes('First Reminder') ? 1 : 0;
const modalBody = document.querySelector('#confirmModal .px-7.py-3 p');
if (currentLevel >= reminderType) {
// Warning: trying to send same or earlier reminder
const currentReminderName = currentLevel === 3 ? 'Final Reminder' :
currentLevel === 2 ? 'Second Reminder' : 'First Reminder';
modalBody.innerHTML = `
< span class = "text-sm text-gray-600 text-center" >
Send < strong > ${reminderTypeName}< / strong > for enquiry < strong > ${enquiryRef}< / strong > to < strong > ${customerName}< / strong > ?
< / span >
< div class = "mt-3 p-3 bg-yellow-50 border border-yellow-200 rounded-md" >
< div class = "flex items-start gap-2" >
< i class = "fas fa-exclamation-triangle text-yellow-600 mt-0.5 flex-shrink-0" > < / i >
< span class = "text-sm text-yellow-800" >
< strong > Warning:< / strong > The customer has already received their < strong > ${currentReminderName}< / strong > .
< / span >
< / div >
< / div >
`;
} else {
// Normal confirmation
modalBody.innerHTML = `
< span class = "text-sm text-gray-600 text-center" >
Send < strong > ${reminderTypeName}< / strong > for enquiry < strong > ${enquiryRef}< / strong > to < strong > ${customerName}< / strong > ?
< / span >
`;
}
2025-12-03 04:59:57 -08:00
document.getElementById('confirmModal').classList.remove('hidden');
}
function hideConfirmModal() {
document.getElementById('confirmModal').classList.add('hidden');
currentForm = null;
currentReminderType = null;
}
2025-12-06 17:44:30 -08:00
function showDisableModal(quoteID, enquiryRef) {
currentQuoteID = quoteID;
2025-12-06 21:53:59 -08:00
document.getElementById('disableModalQuoteID').textContent = quoteID;
2025-12-06 17:44:30 -08:00
document.getElementById('disableModalEnquiryRef').textContent = enquiryRef;
document.getElementById('disableModal').classList.remove('hidden');
// Close any open dropdowns
document.querySelectorAll('form > div.absolute').forEach(d => d.classList.add('hidden'));
}
function hideDisableModal() {
document.getElementById('disableModal').classList.add('hidden');
currentQuoteID = null;
}
2025-12-06 21:53:59 -08:00
function showEnableModal(quoteID, enquiryRef) {
currentQuoteID = quoteID;
document.getElementById('enableModalEnquiryRef').textContent = enquiryRef;
document.getElementById('enableModal').classList.remove('hidden');
}
function hideEnableModal() {
document.getElementById('enableModal').classList.add('hidden');
currentQuoteID = null;
}
2025-12-03 04:59:57 -08:00
document.getElementById('modalCancelBtn').addEventListener('click', hideConfirmModal);
2025-12-06 21:53:59 -08:00
document.getElementById('modalConfirmBtn').addEventListener('click', async function() {
2025-12-03 04:59:57 -08:00
if (currentForm & & currentReminderType) {
2025-12-06 21:53:59 -08:00
const formData = new FormData(currentForm);
formData.append('reminder_type', currentReminderType);
try {
const response = await fetch('/go/quotes/send-reminder', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
body: formData
});
if (response.ok) {
// Update the row to show the reminder was sent
const row = currentForm.closest('tr');
const reminderCell = row.querySelector('td:nth-child(6)');
const reminderSentCell = row.querySelector('td:nth-child(7)');
// Update reminder type badge
const reminderTypeName = currentReminderType === 1 ? 'First Reminder' :
currentReminderType === 2 ? 'Second Reminder' : 'Final Reminder';
const colorClass = currentReminderType === 1 ? 'bg-blue-100 text-blue-700 border-blue-200' :
currentReminderType === 2 ? 'bg-yellow-100 text-yellow-700 border-yellow-200' :
'bg-red-100 text-red-700 border-red-200';
reminderCell.innerHTML = `< span class = "inline-block px-3 py-1 rounded-full text-xs font-semibold ${colorClass}" > ${reminderTypeName}< / span > `;
// Update reminder sent time to "just now"
reminderSentCell.innerHTML = '< span class = "localdatetime" > just now< / span > ';
// Update the button to show next reminder type
const buttonGroup = currentForm.querySelector('.inline-flex');
const mainButton = buttonGroup.querySelector('button:first-child');
if (currentReminderType === 1) {
mainButton.textContent = 'Send Second Reminder';
mainButton.setAttribute('onclick', `showConfirmModal(this, 2, '${formData.get('enquiry_ref')}', '${formData.get('customer_name')}', 'Second Reminder')`);
} else if (currentReminderType === 2) {
mainButton.textContent = 'Send Final Reminder';
mainButton.setAttribute('onclick', `showConfirmModal(this, 3, '${formData.get('enquiry_ref')}', '${formData.get('customer_name')}', 'Final Reminder')`);
}
} else {
alert('Failed to send reminder. Please try again.');
}
} catch (error) {
alert('Error sending reminder: ' + error.message);
}
2025-12-03 04:59:57 -08:00
}
hideConfirmModal();
});
2025-12-06 17:44:30 -08:00
document.getElementById('disableModalCancelBtn').addEventListener('click', hideDisableModal);
2025-12-06 21:53:59 -08:00
document.getElementById('disableModalConfirmBtn').addEventListener('click', async function() {
2025-12-06 17:44:30 -08:00
if (currentQuoteID) {
2025-12-06 21:53:59 -08:00
const formData = new FormData();
formData.append('quote_id', currentQuoteID);
2025-12-06 17:44:30 -08:00
2025-12-06 21:53:59 -08:00
try {
const response = await fetch('/go/quotes/disable-reminders', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
body: formData
});
if (response.ok) {
// Find and update all rows for this quote
const rows = document.querySelectorAll(`tr`);
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 > ';
// Disable the action buttons
const buttonGroup = row.querySelector('.inline-flex');
if (buttonGroup) {
buttonGroup.innerHTML = '< span class = "text-gray-500 text-xs" > Disabled< / span > ';
}
}
});
} else {
alert('Failed to disable reminders. Please try again.');
}
} catch (error) {
alert('Error disabling reminders: ' + error.message);
}
2025-12-06 17:44:30 -08:00
}
hideDisableModal();
});
2025-12-03 04:59:57 -08:00
// Close modal when clicking outside
document.getElementById('confirmModal').addEventListener('click', function(e) {
if (e.target === this) {
hideConfirmModal();
}
});
2025-12-06 17:44:30 -08:00
document.getElementById('disableModal').addEventListener('click', function(e) {
if (e.target === this) {
hideDisableModal();
}
});
2025-12-06 21:53:59 -08:00
document.getElementById('enableModalCancelBtn').addEventListener('click', hideEnableModal);
document.getElementById('enableModalConfirmBtn').addEventListener('click', async function() {
if (currentQuoteID) {
const formData = new FormData();
formData.append('quote_id', currentQuoteID);
try {
const response = await fetch('/go/quotes/enable-reminders', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
body: formData
});
if (response.ok) {
// Find and update all rows for this quote
const rows = document.querySelectorAll(`tr`);
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 > `;
}
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 } " >
2025-12-06 22:35:21 -08:00
< div class = "relative inline-block" >
2025-12-06 21:53:59 -08:00
< div class = "inline-flex rounded-md shadow-sm" role = "group" >
${buttonHTML}
${dropdownHTML}
< / div >
2025-12-06 22:35:21 -08:00
< 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;" >
2025-12-06 21:53:59 -08:00
< 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 >
2025-12-06 22:35:21 -08:00
< / div >
2025-12-06 21:53:59 -08:00
`;
}
});
} else {
alert('Failed to enable reminders. Please try again.');
}
} catch (error) {
alert('Error enabling reminders: ' + error.message);
}
}
hideEnableModal();
});
document.getElementById('enableModal').addEventListener('click', function(e) {
if (e.target === this) {
hideEnableModal();
}
});
2025-12-03 04:59:57 -08:00
function toggleDropdown(button) {
const dropdown = button.parentElement.nextElementSibling;
const allDropdowns = document.querySelectorAll('form > div.absolute');
// Close all other dropdowns
allDropdowns.forEach(d => {
if (d !== dropdown) {
d.classList.add('hidden');
}
});
// Toggle current dropdown
dropdown.classList.toggle('hidden');
// Close dropdown when clicking outside
if (!dropdown.classList.contains('hidden')) {
setTimeout(() => {
document.addEventListener('click', function closeDropdown(e) {
if (!dropdown.contains(e.target) & & !button.contains(e.target)) {
dropdown.classList.add('hidden');
document.removeEventListener('click', closeDropdown);
}
});
}, 0);
}
}
2025-07-19 23:50:09 -07:00
// Convert .localdate to browser local date, .localdatetime to browser local date+time (no offset)
function formatLocalDate(isoString) {
if (!isoString) return '';
var d = new Date(isoString);
if (isNaN(d.getTime())) return isoString;
return d.toLocaleDateString();
}
function formatLocalDateTime(isoString) {
if (!isoString) return '';
var d = new Date(isoString);
if (isNaN(d.getTime())) return isoString;
// Show date and time in local time, no offset
return d.toLocaleString([], { hour: '2-digit', minute: '2-digit', second: '2-digit', year: 'numeric', month: '2-digit', day: '2-digit' });
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.localdate').forEach(function(el) {
var iso = el.textContent.trim();
if (iso) {
el.textContent = formatLocalDate(iso);
}
});
document.querySelectorAll('.localdatetime').forEach(function(el) {
var iso = el.textContent.trim();
if (iso) {
el.textContent = formatLocalDateTime(iso);
}
});
});
< / script >
2025-07-13 05:50:47 -07:00
{{end}}