From bf34f1ad3ce76dfd4b47fcc700c27fe21d3efa0e Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 00:11:13 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- .../cases/convert-to-collections-dialog.tsx | 62 +++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/components/cases/convert-to-collections-dialog.tsx b/src/components/cases/convert-to-collections-dialog.tsx index d3df272..3fd2909 100644 --- a/src/components/cases/convert-to-collections-dialog.tsx +++ b/src/components/cases/convert-to-collections-dialog.tsx @@ -181,9 +181,10 @@ export function ConvertToCollectionsDialog({ } setSubmitting(true); try { - // Resolve each selected contact to a homeowner row (find by name on this client, else create). const selectedContacts = contacts.filter((c) => selected.has(c.id)); + // Resolve each selected contact to a homeowner row (find by name on + // this client, else create). Returns the homeowner_id, in input order. let existingHomeowners: any[] = []; if (clientId && selectedContacts.length > 0) { const { data: hos } = await supabase @@ -193,7 +194,7 @@ export function ConvertToCollectionsDialog({ existingHomeowners = hos ?? []; } - const homeownerIds: string[] = []; + const homeownerIdByContact = new Map(); for (const c of selectedContacts) { const { first, last } = splitName(c.name); const match = existingHomeowners.find( @@ -202,7 +203,7 @@ export function ConvertToCollectionsDialog({ (h.last_name || "").toLowerCase().trim() === last.toLowerCase(), ); if (match) { - homeownerIds.push(match.id); + homeownerIdByContact.set(c.id, match.id); continue; } if (!clientId) { @@ -228,28 +229,67 @@ export function ConvertToCollectionsDialog({ setSubmitting(false); return; } - homeownerIds.push(newHo.id); + homeownerIdByContact.set(c.id, newHo.id); } - // Skip homeowners that already have a collection on this case const { data: existingCols } = await supabase .from("collections") .select("homeowner_id") .eq("case_id", caseId); - const existingSet = new Set( + const existingHomeownerSet = new Set( (existingCols ?? []) .map((r: any) => r.homeowner_id) .filter((id: string | null): id is string => !!id), ); + const hasAnyCollection = (existingCols ?? []).length > 0; - const rows: any[] = homeownerIds - .filter((id) => !existingSet.has(id)) - .map((homeowner_id) => ({ + const rows: any[] = []; + + if (combine && selectedContacts.length > 0) { + // ONE combined collection for the case. Use the user-picked primary, + // or the first selected contact, as homeowner_id. + const primaryContact = + selectedContacts.find((c) => c.id === primaryId) ?? selectedContacts[0]; + const primaryHomeownerId = homeownerIdByContact.get(primaryContact.id); + if (!primaryHomeownerId) { + toast.error("Could not resolve a primary homeowner"); + setSubmitting(false); + return; + } + if (hasAnyCollection) { + toast.info( + "This case already has a collection. Use Merge on the Collections tab to combine them.", + ); + setSubmitting(false); + return; + } + const otherNames = selectedContacts + .filter((c) => c.id !== primaryContact.id) + .map((c) => c.name); + const combinedName = + otherNames.length > 0 + ? `${primaryContact.name} + ${otherNames.length} other${otherNames.length === 1 ? "" : "s"}` + : null; + rows.push({ case_id: caseId, - homeowner_id, + homeowner_id: primaryHomeownerId, status, + name: combinedName, created_by: user?.id, - })); + }); + } else if (selectedContacts.length > 0) { + // Per-homeowner mode (legacy) + for (const c of selectedContacts) { + const homeowner_id = homeownerIdByContact.get(c.id)!; + if (existingHomeownerSet.has(homeowner_id)) continue; + rows.push({ + case_id: caseId, + homeowner_id, + status, + created_by: user?.id, + }); + } + } if (includeEmpty) { rows.push({