Fix passkey login tracking, add email opt-out UI guards, and add Quick/Full quote mode toggle
- PasskeyController: set LastLoginDate on passkey sign-in so Company Health and audit pages show accurate last-login times (was always showing 'Never') - Jobs/Index status modal: disable 'Notify customer' email toggle and show warning when customer has notifications turned off; CustomerNotifyByEmail added to JobListDto + JobProfile mapping + data-customer-notify attribute - Quotes/Create: disable 'Send quote via email' checkbox with 'Notifications off' badge when selected customer has email opt-out; ViewBag.CustomerEmailOptOutIds added alongside existing CustomerTaxExemptIds pattern - Quotes/Create: Quick Quote / Full Quote segmented toggle at top of form; hides non-essential fields (dates, notes, tags, oven, discount, photos) in Quick mode; selection persisted in localStorage - InvoicesController Send action: improved error logging and user-facing warning when PDF generation or email dispatch fails after status is saved - item-wizard.js: guard item restoration with try/catch; ensure writeHiddenFields always runs on form submit via capture-phase listener - Help docs and AI knowledge base updated for all new features Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -195,6 +195,7 @@
|
||||
data-job-number="@job.JobNumber"
|
||||
data-status-id="@job.JobStatusId"
|
||||
data-status-name="@job.StatusDisplayName"
|
||||
data-customer-notify="@job.CustomerNotifyByEmail.ToString().ToLower()"
|
||||
title="Click to change status">
|
||||
<span class="pcl-chip-dot"></span>@job.StatusDisplayName
|
||||
</span>
|
||||
@@ -511,6 +512,9 @@
|
||||
<i class="bi bi-envelope me-1"></i>Notify customer via email
|
||||
</label>
|
||||
</div>
|
||||
<div id="statusModalEmailOptOutNote" class="alert alert-warning alert-permanent py-1 px-2 mt-2 small" style="display:none;">
|
||||
<i class="bi bi-bell-slash me-1"></i>This customer has email notifications turned off.
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
@@ -745,12 +749,22 @@
|
||||
currentJobStatusId = this.getAttribute('data-status-id');
|
||||
const jobNumber = this.getAttribute('data-job-number');
|
||||
const statusName = this.getAttribute('data-status-name');
|
||||
const customerNotify = this.getAttribute('data-customer-notify') !== 'false';
|
||||
|
||||
// Update modal content
|
||||
document.getElementById('modalStatusJobNumber').textContent = jobNumber;
|
||||
document.getElementById('modalCurrentStatus').textContent = statusName;
|
||||
document.getElementById('statusSelect').value = currentJobStatusId;
|
||||
|
||||
// Reflect customer email opt-out preference
|
||||
const emailCheckbox = document.getElementById('statusModalSendEmail');
|
||||
const emailOptOutNote = document.getElementById('statusModalEmailOptOutNote');
|
||||
if (emailCheckbox) {
|
||||
emailCheckbox.disabled = !customerNotify;
|
||||
if (!customerNotify) emailCheckbox.checked = false;
|
||||
}
|
||||
if (emailOptOutNote) emailOptOutNote.style.display = customerNotify ? 'none' : 'block';
|
||||
|
||||
// Show modal
|
||||
const modal = new bootstrap.Modal(document.getElementById('statusModal'));
|
||||
modal.show();
|
||||
|
||||
Reference in New Issue
Block a user