Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 04:23:52 +00:00
co-authored by renee-png
parent c007c49c8e
commit 4899b45565
+67
View File
@@ -136,6 +136,73 @@ function ContactsIndex() {
setOpen(true);
};
const toggleOne = (id: string) => {
setSelected((s) => {
const next = new Set(s);
if (next.has(id)) next.delete(id);
else next.add(id);
return next;
});
};
const toggleAllVisible = () => {
const visibleIds = filtered.map((r) => r.id);
const allSelected = visibleIds.every((id) => selected.has(id));
setSelected((s) => {
const next = new Set(s);
if (allSelected) visibleIds.forEach((id) => next.delete(id));
else visibleIds.forEach((id) => next.add(id));
return next;
});
};
const clearSelection = () => setSelected(new Set());
const bulkArchive = async (archived: boolean) => {
const ids = Array.from(selected);
if (!ids.length) return;
const patch = { archived_at: archived ? new Date().toISOString() : null };
const { error } = await (supabase.from("contacts") as any).update(patch).in("id", ids);
if (error) {
toast.error(error.message);
return;
}
toast.success(`${ids.length} contact${ids.length === 1 ? "" : "s"} ${archived ? "archived" : "restored"}`);
clearSelection();
load();
};
const bulkDelete = async () => {
const ids = Array.from(selected);
if (!ids.length) return;
if (!confirm(`Delete ${ids.length} contact${ids.length === 1 ? "" : "s"}? This will also remove all case and client links.`)) return;
const { error } = await supabase.from("contacts").delete().in("id", ids);
if (error) {
toast.error(error.message);
return;
}
toast.success(`${ids.length} contact${ids.length === 1 ? "" : "s"} deleted`);
clearSelection();
load();
};
const bulkChangeType = async (newType: string) => {
const ids = Array.from(selected);
if (!ids.length || !newType) return;
const { error } = await supabase.from("contacts").update({ contact_type: newType }).in("id", ids);
if (error) {
toast.error(error.message);
return;
}
const label = CONTACT_TYPES.find((t) => t.value === newType)?.label ?? newType;
toast.success(`${ids.length} contact${ids.length === 1 ? "" : "s"} changed to ${label}`);
setBulkType("");
clearSelection();
load();
};
const visibleIds = filtered.map((r) => r.id);
const allVisibleSelected = visibleIds.length > 0 && visibleIds.every((id) => selected.has(id));
const someVisibleSelected = visibleIds.some((id) => selected.has(id));
return (
<PageContainer>
<PageHeader