cmc-sales/go/templates/quotes/index.html

605 lines
43 KiB
HTML

{{define "content"}}
<h1 class="text-3xl font-bold mb-4 text-gray-800">Quotes Expiring</h1>
<div class="px-4">
<!-- Expiring Soon Section -->
<h2 class="text-xl font-semibold mt-6 mb-2">Expiring Soon</h2>
<table class="w-full border text-center align-middle mt-1">
<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>
<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>
<th class="px-4 py-3 border font-semibold text-gray-700 align-middle">Reminder</th>
<th class="px-4 py-3 border font-semibold text-gray-700 align-middle">Reminder Sent</th>
<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>
</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>
<td class="px-4 py-2 border align-middle"><a href="/enquiries/view/{{.EnquiryID}}" class="text-blue-600 underline">{{.EnquiryRef}}</a></td>
<td class="px-4 py-2 border align-middle">{{.Username}}</td>
<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>
<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}}{{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}}{{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}}{{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}}{{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{{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">
{{if .LatestReminderSent}}<span class="localdatetime">{{.LatestReminderSent}}</span>{{else}}-{{end}}
</td>
<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}}">
{{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}}
<div class="relative inline-block">
<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>
<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('{{.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>
</div>
{{end}}
</form>
</td>
</tr>
{{else}}
<tr><td colspan="8" class="px-4 py-2 border text-center align-middle">No quotes expiring soon.</td></tr>
{{end}}
</tbody>
</table>
<!-- Recently Expired Quotes Section -->
<h2 class="text-xl font-semibold mt-6 mb-2">Recently Expired</h2>
<table class="w-full border mb-6 text-center align-middle mt-1">
<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>
<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>
<th class="px-4 py-3 border font-semibold text-gray-700 align-middle">Reminder</th>
<th class="px-4 py-3 border font-semibold text-gray-700 align-middle">Reminder Sent</th>
<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>
</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>
<td class="px-4 py-2 border align-middle"><a href="/enquiries/view/{{.EnquiryID}}" class="text-blue-600 underline">{{.EnquiryRef}}</a></td>
<td class="px-4 py-2 border align-middle">{{.Username}}</td>
<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>
<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}}{{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}}{{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}}{{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}}{{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{{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">
{{if .LatestReminderSent}}<span class="localdatetime">{{.LatestReminderSent}}</span>{{else}}-{{end}}
</td>
<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}}">
{{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}}
<div class="relative inline-block">
<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>
<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('{{.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>
</div>
{{end}}
</form>
</td>
</tr>
{{else}}
<tr><td colspan="8" class="px-4 py-2 border text-center align-middle">No recently expired quotes.</td></tr>
{{end}}
</tbody>
</table>
</div>
<!-- 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>
<!-- 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">
<div class="relative top-20 mx-auto p-5 border w-[500px] 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-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>
</div>
<div class="px-7 py-3">
<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>
<!-- 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">
<div class="relative top-20 mx-auto p-5 border w-[500px] 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-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>
</div>
<div class="px-7 py-3">
<p class="text-sm text-gray-600 text-center">
This will prevent future automatic reminders for quote <strong id="disableModalQuoteID"></strong> in enquiry <strong id="disableModalEnquiryRef"></strong>.
</p>
</div>
<div class="flex gap-3 px-4 py-3">
<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">
Cancel
</button>
<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">
Disable Reminders
</button>
</div>
</div>
</div>
</div>
<script>
let currentForm = null;
let currentReminderType = null;
let currentQuoteID = null;
function showConfirmModal(button, reminderType, enquiryRef, customerName, reminderTypeName) {
currentForm = button.closest('form');
currentReminderType = reminderType;
// 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>
`;
}
document.getElementById('confirmModal').classList.remove('hidden');
}
function hideConfirmModal() {
document.getElementById('confirmModal').classList.add('hidden');
currentForm = null;
currentReminderType = null;
}
function showDisableModal(quoteID, enquiryRef) {
currentQuoteID = quoteID;
document.getElementById('disableModalQuoteID').textContent = quoteID;
document.getElementById('disableModalEnquiryRef').textContent = enquiryRef;
document.getElementById('disableModal').classList.remove('hidden');
// Close any open dropdowns
document.querySelectorAll('div.absolute.right-0').forEach(d => d.classList.add('hidden'));
}
function hideDisableModal() {
document.getElementById('disableModal').classList.add('hidden');
currentQuoteID = null;
}
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;
}
document.getElementById('modalCancelBtn').addEventListener('click', hideConfirmModal);
document.getElementById('modalConfirmBtn').addEventListener('click', async function() {
if (currentForm && currentReminderType) {
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);
}
}
hideConfirmModal();
});
document.getElementById('disableModalCancelBtn').addEventListener('click', hideDisableModal);
document.getElementById('disableModalConfirmBtn').addEventListener('click', async function() {
if (currentQuoteID) {
const formData = new URLSearchParams();
formData.append('quote_id', currentQuoteID);
try {
const response = await fetch('/go/quotes/disable-reminders', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'
},
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}"]`)) {
const enquiryRef = form.querySelector('input[name="enquiry_ref"]').value;
// 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);
}
}
});
} else {
alert('Failed to disable reminders. Please try again.');
}
} catch (error) {
alert('Error disabling reminders: ' + error.message);
}
}
hideDisableModal();
});
// Close modal when clicking outside
document.getElementById('confirmModal').addEventListener('click', function(e) {
if (e.target === this) {
hideConfirmModal();
}
});
document.getElementById('disableModal').addEventListener('click', function(e) {
if (e.target === this) {
hideDisableModal();
}
});
document.getElementById('enableModalCancelBtn').addEventListener('click', hideEnableModal);
document.getElementById('enableModalConfirmBtn').addEventListener('click', async function() {
if (currentQuoteID) {
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',
'Content-Type': 'application/x-www-form-urlencoded'
},
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}"]`)) {
const enquiryRef = form.querySelector('input[name="enquiry_ref"]').value;
// 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}')`);
}
}
// 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 {
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();
}
});
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);
}
}
// 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>
{{end}}