From 2c1ff61b29d3650de57d8a948245b62309eed3f4 Mon Sep 17 00:00:00 2001 From: Krao Hasanee Date: Wed, 15 Jul 2026 16:45:37 -0400 Subject: [PATCH] fix: popups no longer close on backdrop click, only via explicit close/cancel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clicking the dimmed area outside a modal (+Task, +Invoice, expense, review, etc.) accidentally dismissed it and lost in-progress input. Every popup already has an explicit Cancel/Close/✕ button, so the backdrop click handler is removed; also drops the now-dead onClose/blockClose prop plumbing that only existed to support it. Co-Authored-By: Claude Sonnet 5 --- src/components/InvoiceDetailPopup.jsx | 4 +--- src/pages/BrandBook.jsx | 2 -- src/pages/Profile.jsx | 1 - src/pages/ProjectDetail.jsx | 4 ++-- src/pages/TaskDetail.jsx | 8 ++++---- src/pages/Tasks.jsx | 4 ++-- src/pages/client/ClientMyInvoices.jsx | 2 -- src/pages/external/ExternalMyInvoices.jsx | 4 +--- src/pages/team/TeamInvoiceDetail.jsx | 2 -- src/pages/team/TeamInvoices.jsx | 8 +++----- 10 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/components/InvoiceDetailPopup.jsx b/src/components/InvoiceDetailPopup.jsx index 05d415a..7d35a4b 100644 --- a/src/components/InvoiceDetailPopup.jsx +++ b/src/components/InvoiceDetailPopup.jsx @@ -15,8 +15,6 @@ export default function InvoiceDetailPopup({ title, subtitle, headerRight, - onClose, - blockClose = false, metaContent, // JSX fields rendered in flat meta grid (no cards) metaActions, // optional JSX rendered right-aligned beside meta grid (e.g. Edit Dates) metaCols = 4, // number of grid columns for meta strip @@ -25,7 +23,7 @@ export default function InvoiceDetailPopup({ children, }) { return ( -
{ if (!blockClose) onClose?.(); }}> +
e.stopPropagation()} diff --git a/src/pages/BrandBook.jsx b/src/pages/BrandBook.jsx index 18d0666..dff0465 100644 --- a/src/pages/BrandBook.jsx +++ b/src/pages/BrandBook.jsx @@ -2353,7 +2353,6 @@ function DimensionEditorModal({ sourceImage, onApply, onCancel }) { return (
{ if (e.target === e.currentTarget) onCancel(); }} >
@@ -3436,7 +3435,6 @@ function PhotoEditorModal({ return (
{ if (e.target === e.currentTarget) onCancel(); }} >
{/* Header */} diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx index fa5e777..2e42065 100644 --- a/src/pages/Profile.jsx +++ b/src/pages/Profile.jsx @@ -642,7 +642,6 @@ export default function ProfilePage() { {isSelfView && editOpen && (
{ if (!savingProfile) setEditOpen(false); }} >
{showClientTask && isClient && ( -
{ setShowClientTask(false); setClientTaskKey(k => k + 1); setClientTaskError(''); }}> +
e.stopPropagation()}>
New Task
{ setAddingMember(false); setSelectedExts(new Set()); }}> +
e.stopPropagation()}>
Manage Subcontractors
diff --git a/src/pages/TaskDetail.jsx b/src/pages/TaskDetail.jsx index cf2243d..1a93de5 100644 --- a/src/pages/TaskDetail.jsx +++ b/src/pages/TaskDetail.jsx @@ -1035,7 +1035,7 @@ export default function TaskDetail() {
{reviewModal && ( -
{ if (!reviewSaving) { setReviewModal(false); setReviewFiles([]); setReviewNotes(''); } }}> +
e.stopPropagation()}>
Place in Review
@@ -1054,7 +1054,7 @@ export default function TaskDetail() { )} {revisionModal && ( -
{ if (!revisionSaving) { setRevisionModal(false); setRevisionForm({ description: '', deadline: '' }); setRevisionFiles([]); } }}> +
e.stopPropagation()}>
Request Revision
@@ -1090,7 +1090,7 @@ export default function TaskDetail() { )} {rejectModal && ( -
{ if (!rejectSaving) { setRejectModal(false); setRejectNote(''); } }}> +
e.stopPropagation()}>
Reject Task
@@ -1114,7 +1114,7 @@ export default function TaskDetail() { )} {amendModal && ( -
{ setAmendModal(false); setAmendForm({ description: '' }); setAmendFiles([]); }}> +
e.stopPropagation()}>
Amend Request
diff --git a/src/pages/Tasks.jsx b/src/pages/Tasks.jsx index 721c2e7..36d38cc 100644 --- a/src/pages/Tasks.jsx +++ b/src/pages/Tasks.jsx @@ -653,7 +653,7 @@ export default function RequestsPage() { > {/* Add project modal */} {showAddProjectForm && ( -
{ setShowAddProjectForm(false); setAddProjectForm({ name: '', companyId: '' }); setAddProjectError(''); }}> +
e.stopPropagation()}>
Add Project
@@ -682,7 +682,7 @@ export default function RequestsPage() { {/* Add task modal */} {showAddForm && ( -
{ setShowAddForm(false); setAddFormKey(k => k + 1); setAddError(''); }}> +
e.stopPropagation()}>
{isTeam ? 'Add Task' : 'New Task'}
diff --git a/src/pages/client/ClientMyInvoices.jsx b/src/pages/client/ClientMyInvoices.jsx index 132c8ba..84ceb05 100644 --- a/src/pages/client/ClientMyInvoices.jsx +++ b/src/pages/client/ClientMyInvoices.jsx @@ -103,8 +103,6 @@ function ClientInvoiceModal({ invoice, onClose }) { title={invoice.invoice_number} subtitle={invoice.bill_to || company?.name} headerRight={} - onClose={onClose} - blockClose={Boolean(downloading)} metaContent={<>
Invoice Date
{invoice.invoice_date ? new Date(invoice.invoice_date).toLocaleDateString() : '—'}
Due Date
{invoice.due_date ? new Date(invoice.due_date).toLocaleDateString() : '—'}
diff --git a/src/pages/external/ExternalMyInvoices.jsx b/src/pages/external/ExternalMyInvoices.jsx index 8c3ee04..0dd855e 100644 --- a/src/pages/external/ExternalMyInvoices.jsx +++ b/src/pages/external/ExternalMyInvoices.jsx @@ -428,7 +428,7 @@ export default function MyInvoices() {
{showInvoiceForm && ( -
setShowInvoiceForm(false)}> +
e.stopPropagation()} @@ -469,8 +469,6 @@ export default function MyInvoices() { title={inv?.invoice_number || 'Subcontractor Invoice'} subtitle={`${currentUser?.name || 'Subcontractor'}${currentUser?.email ? ` · ${currentUser.email}` : ''}`} headerRight={inv ? : null} - onClose={() => { if (!busy) { setViewingInvoice(null); setDetailError(''); } }} - blockClose={busy} loading={detailLoading && !inv} metaContent={inv ? <>
Created
{inv.created_at ? new Date(inv.created_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—'}
diff --git a/src/pages/team/TeamInvoiceDetail.jsx b/src/pages/team/TeamInvoiceDetail.jsx index 2c2123e..0b2fa78 100644 --- a/src/pages/team/TeamInvoiceDetail.jsx +++ b/src/pages/team/TeamInvoiceDetail.jsx @@ -403,8 +403,6 @@ export function TeamInvoiceDetailPanel({ label={`${invoice.status ? invoice.status.charAt(0).toUpperCase() + invoice.status.slice(1) : '—'}${isOverdue ? ' · Overdue' : ''}`} /> ) : null} - onClose={onClose} - blockClose={saving || Boolean(generating)} loading={loading} metaContent={invoice ? <>
diff --git a/src/pages/team/TeamInvoices.jsx b/src/pages/team/TeamInvoices.jsx index f256dce..f051044 100644 --- a/src/pages/team/TeamInvoices.jsx +++ b/src/pages/team/TeamInvoices.jsx @@ -1761,8 +1761,6 @@ export default function Invoices() { title={invoice.invoice_number || 'Subcontractor Invoice'} subtitle={`${invoice.profile?.name || 'External'}${invoice.profile?.email ? ` · ${invoice.profile.email}` : ''}`} headerRight={} - onClose={() => { if (!markingPaid) setViewingSubInvoice(null); }} - blockClose={Boolean(markingPaid)} metaContent={<>
Submitted
{invoice.submitted_at ? new Date(invoice.submitted_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—'}
Paid
{invoice.paid_at ? new Date(invoice.paid_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—'}
@@ -1819,7 +1817,7 @@ export default function Invoices() { newExpense.removeReceipt === true ); return ( -
{ setViewingExpense(null); setExpenseDetailEditing(false); }}> +
e.stopPropagation()}> {/* Main content row */}
@@ -1914,7 +1912,7 @@ export default function Invoices() { const LABEL = { ...FIELD_LABEL_STYLE, marginBottom: 3 }; const INPUT = FINANCE_MODAL_INPUT_STYLE; return ( -
+
e.stopPropagation()}>
{/* Main content row */} @@ -1970,7 +1968,7 @@ export default function Invoices() { const LABEL = { ...FIELD_LABEL_STYLE, marginBottom: 3 }; const INPUT = FINANCE_MODAL_INPUT_STYLE; return ( -
{ if (!invSaving) invClose(); }}> +
e.stopPropagation()}>