From 6638030e2e079852226482ba7b9e92ae6d6753c4 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Sat, 25 Apr 2026 15:00:05 -0500 Subject: [PATCH] Fixes --- public/js/modals/email-modal.js | 26 +++++++++++++++--------- public/js/views/invoice-view.js | 36 ++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/public/js/modals/email-modal.js b/public/js/modals/email-modal.js index 173114b..36be6c1 100644 --- a/public/js/modals/email-modal.js +++ b/public/js/modals/email-modal.js @@ -20,7 +20,11 @@ function ensureModalElement() { document.body.appendChild(modal); } } - +function getEmailModalTitle(invoice, isOverdue) { + if (isOverdue) return `⏰ Send Reminder for Invoice #${invoice.invoice_number || invoice.id}`; + if (invoice.email_status === 'sent') return `🔁 Resend Invoice #${invoice.invoice_number || invoice.id}`; + return `📤 Send Invoice #${invoice.invoice_number || invoice.id}`; +} function renderModalContent() { const modal = document.getElementById('email-modal'); if (!modal) return; @@ -28,7 +32,18 @@ function renderModalContent() { const defaultEmail = currentInvoice.email || ''; const existingStripeUrl = currentInvoice.stripe_payment_link_url || ''; const stripeStatus = currentInvoice.stripe_payment_status || ''; + + // Detect overdue: unpaid + older than 30 days + const invoiceDateParsed = currentInvoice.invoice_date + ? new Date(currentInvoice.invoice_date.split('T')[0]) + : null; + const daysSinceInvoice = invoiceDateParsed + ? Math.floor((new Date() - invoiceDateParsed) / 86400000) + : 0; + const isOverdue = !currentInvoice.paid_date && daysSinceInvoice > 30; + const modalTitle = getEmailModalTitle(currentInvoice, isOverdue); + // Status indicator for existing link let stripeBadgeHtml = ''; if (existingStripeUrl && stripeStatus === 'paid') { @@ -137,15 +152,6 @@ function renderModalContent() { paymentText = 'Our terms are Net 30.'; } - // Detect overdue: unpaid + older than 30 days - const invoiceDateParsed = currentInvoice.invoice_date - ? new Date(currentInvoice.invoice_date.split('T')[0]) - : null; - const daysSinceInvoice = invoiceDateParsed - ? Math.floor((new Date() - invoiceDateParsed) / 86400000) - : 0; - const isOverdue = !currentInvoice.paid_date && daysSinceInvoice > 30; - let defaultHtml = ''; if (isOverdue) { diff --git a/public/js/views/invoice-view.js b/public/js/views/invoice-view.js index 7409528..61e50cd 100644 --- a/public/js/views/invoice-view.js +++ b/public/js/views/invoice-view.js @@ -171,6 +171,30 @@ function groupInvoices(filtered) { return new Map([...groups.entries()].sort((a, b) => b[0].localeCompare(a[0]))); } +function getInvoiceEmailButtonLabel(invoice, overdue) { + if (overdue) { + return { + text: '⏰ Send Reminder', + title: 'Send overdue reminder with invoice PDF and optional Stripe payment link', + className: 'bg-red-100 text-red-700 hover:bg-red-200' + }; + } + + if (invoice.email_status === 'sent') { + return { + text: '🔁 Resend Invoice', + title: 'Resend invoice with PDF and optional Stripe payment link', + className: 'bg-purple-100 text-purple-700 hover:bg-purple-200' + }; + } + + return { + text: '📤 Send Invoice', + title: 'Send invoice with PDF and optional Stripe payment link', + className: 'bg-blue-100 text-blue-700 hover:bg-blue-200' + }; +} + // ============================================================ // Render // ============================================================ @@ -292,9 +316,15 @@ function renderInvoiceRow(invoice) { const delBtn = ``; - const stripeEmailBtn = (hasQbo && !paid && (invoice.email_status !== 'sent' || ((invoice.email_status === 'sent' && overdue)))) - ? `` - : ''; + const emailAction = getInvoiceEmailButtonLabel(invoice, overdue); + + const stripeEmailBtn = (hasQbo && !paid) + ? `` + : ''; const stripeCheckBtn = (invoice.stripe_payment_link_id && !paid) ? ``