Added surname pre-select logic

X-Lovable-Edit-ID: edt-5e55bd3f-4450-49e6-be3b-5cbc9c8e56a8
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 23:34:38 +00:00
co-authored by renee-png
3 changed files with 64 additions and 12 deletions
+36 -8
View File
@@ -319,6 +319,7 @@ export function CaseCollectionsTab({
onOpenChange={setAddOpen}
caseId={caseId}
clientId={clientId}
caseTitle={caseRecord.title || ""}
homeowners={homeowners}
existingHomeownerIds={collections.map((c) => c.homeowner_id)}
onCreated={load}
@@ -846,12 +847,35 @@ function BucketCell({ value, danger, positive }: { value: number; danger?: boole
}
// Extract defendant surname from a case title like
// "Corner Lake Estates HOA v Benitez [2074 Corner Glen Drive]"
function extractDefendantSurname(title: string): string | null {
if (!title) return null;
// Match " v " or " v. " or " vs " (case-insensitive)
const m = title.match(/\sv\.?s?\.?\s+([A-Za-z'’\-]+)/i);
if (!m) return null;
return m[1].trim().toLowerCase();
}
function findUniqueHomeownerByTitle(
title: string,
homeowners: any[],
): any | null {
const surname = extractDefendantSurname(title);
if (!surname) return null;
const matches = homeowners.filter(
(h) => (h.last_name || "").toLowerCase() === surname,
);
return matches.length === 1 ? matches[0] : null;
}
// ─── Add collection dialog ──────────────────────────────────────────
function AddCollectionDialog({
open,
onOpenChange,
caseId,
clientId,
caseTitle,
homeowners,
existingHomeownerIds,
onCreated,
@@ -860,6 +884,7 @@ function AddCollectionDialog({
onOpenChange: (v: boolean) => void;
caseId: string;
clientId: string;
caseTitle: string;
homeowners: any[];
existingHomeownerIds: string[];
onCreated: () => void;
@@ -870,18 +895,21 @@ function AddCollectionDialog({
const [notes, setNotes] = useState("");
const [submitting, setSubmitting] = useState(false);
useEffect(() => {
if (open) {
setHomeownerId("");
setStatus("none");
setNotes("");
}
}, [open]);
const available = homeowners.filter(
(h) => !existingHomeownerIds.includes(h.id),
);
useEffect(() => {
if (open) {
// Try to pre-select a homeowner whose surname matches the case title
const match = findUniqueHomeownerByTitle(caseTitle, available);
setHomeownerId(match ? match.id : "");
setStatus("none");
setNotes("");
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [open, caseTitle]);
const submit = async () => {
if (!homeownerId) {
toast.error("Pick a homeowner");
@@ -35,17 +35,26 @@ const STATUS_OPTIONS = [
{ value: "closed", label: "Closed" },
];
function extractDefendantSurname(title: string): string | null {
if (!title) return null;
const m = title.match(/\sv\.?s?\.?\s+([A-Za-z'’\-]+)/i);
if (!m) return null;
return m[1].trim().toLowerCase();
}
export function ConvertToCollectionsDialog({
open,
onOpenChange,
caseId,
clientId,
caseTitle,
onCreated,
}: {
open: boolean;
onOpenChange: (v: boolean) => void;
caseId: string;
clientId: string;
caseTitle?: string;
onCreated?: () => void;
}) {
const { user } = useAuth();
@@ -80,13 +89,27 @@ export function ConvertToCollectionsDialog({
.select("homeowner_id")
.eq("case_id", caseId),
]);
setHomeowners(hos ?? []);
setExistingIds(
new Set((cols ?? []).map((c) => c.homeowner_id).filter((id): id is string => !!id)),
const hoList = hos ?? [];
setHomeowners(hoList);
const existing = new Set(
(cols ?? []).map((c) => c.homeowner_id).filter((id): id is string => !!id),
);
setExistingIds(existing);
// Pre-select homeowner if there's exactly one surname match from the case title
const surname = extractDefendantSurname(caseTitle ?? "");
if (surname) {
const matches = hoList.filter(
(h) =>
(h.last_name || "").toLowerCase() === surname && !existing.has(h.id),
);
if (matches.length === 1) {
setSelected(new Set([matches[0].id]));
}
}
setLoading(false);
})();
}, [open, caseId, clientId]);
}, [open, caseId, clientId, caseTitle]);
const available = useMemo(
() => homeowners.filter((h) => !existingIds.has(h.id)),
+1
View File
@@ -266,6 +266,7 @@ function CaseDetail() {
onOpenChange={setConvertOpen}
caseId={caseId}
clientId={data.client?.id ?? ""}
caseTitle={data.title || ""}
onCreated={() => {
setActiveTab("collections");
load();