diff --git a/src/components/cases/bulk-convert-to-collections-dialog.tsx b/src/components/cases/bulk-convert-to-collections-dialog.tsx index f1a89d6..242acc4 100644 --- a/src/components/cases/bulk-convert-to-collections-dialog.tsx +++ b/src/components/cases/bulk-convert-to-collections-dialog.tsx @@ -72,6 +72,9 @@ export function BulkConvertToCollectionsDialog({ open, onOpenChange, cases, onCr const [selected, setSelected] = useState>(new Set()); const [includeEmpty, setIncludeEmpty] = useState(false); const [emptyName, setEmptyName] = useState(""); + // When true (default), create ONE combined collection per case using the + // first selected contact on that case as the primary homeowner. + const [combine, setCombine] = useState(true); const { eligibleCases, skippedCases, clientId } = useMemo(() => { const counts = new Map(); @@ -95,6 +98,7 @@ export function BulkConvertToCollectionsDialog({ open, onOpenChange, cases, onCr setSearch(""); setIncludeEmpty(false); setEmptyName(""); + setCombine(true); if (eligibleCases.length === 0) { setContactRows([]); return; @@ -245,16 +249,47 @@ export function BulkConvertToCollectionsDialog({ open, onOpenChange, cases, onCr } const rows: any[] = []; - for (const r of selectedRows) { - const homeownerId = contactToHomeowner.get(r.contact_id); - if (!homeownerId) continue; - if (existingPairs.has(`${r.case_id}::${homeownerId}`)) continue; - rows.push({ - case_id: r.case_id, - homeowner_id: homeownerId, - status: "none", - created_by: user?.id, - }); + // Cases that already have ANY collection — skip in combine mode to avoid duplicates. + const casesWithExisting = new Set(); + for (const e of (existing ?? []) as any[]) casesWithExisting.add(e.case_id); + + if (combine) { + // Group selected contacts by case, pick first as primary, attach others by name. + const byCase = new Map(); + for (const r of selectedRows) { + if (!byCase.has(r.case_id)) byCase.set(r.case_id, [] as any); + byCase.get(r.case_id)!.push(r); + } + for (const [caseId, group] of byCase) { + if (casesWithExisting.has(caseId)) continue; + const primary = group[0]; + const primaryHoId = contactToHomeowner.get(primary.contact_id); + if (!primaryHoId) continue; + const others = group.slice(1).map((r) => r.name); + const name = + others.length > 0 + ? `${primary.name} + ${others.length} other${others.length === 1 ? "" : "s"}` + : null; + rows.push({ + case_id: caseId, + homeowner_id: primaryHoId, + status: "none", + name, + created_by: user?.id, + }); + } + } else { + for (const r of selectedRows) { + const homeownerId = contactToHomeowner.get(r.contact_id); + if (!homeownerId) continue; + if (existingPairs.has(`${r.case_id}::${homeownerId}`)) continue; + rows.push({ + case_id: r.case_id, + homeowner_id: homeownerId, + status: "none", + created_by: user?.id, + }); + } } if (includeEmpty) { @@ -410,6 +445,21 @@ export function BulkConvertToCollectionsDialog({ open, onOpenChange, cases, onCr )} +
+ +
+
+
+ + {combine && selected.size > 1 && ( +
+ + +
+ )} +
+