diff --git a/src/routes/cases.index.tsx b/src/routes/cases.index.tsx index 885d091..27071d4 100644 --- a/src/routes/cases.index.tsx +++ b/src/routes/cases.index.tsx @@ -157,6 +157,72 @@ function CasesList() { if (await setArchived("cases", id, archived)) load(); }; + // Selection helpers — clear when switching views. + useEffect(() => { setSelected(new Set()); }, [view]); + const visibleIds = useMemo(() => sorted.map((c) => c.id), [sorted]); + const allSelected = visibleIds.length > 0 && visibleIds.every((id) => selected.has(id)); + const someSelected = selected.size > 0 && !allSelected; + const toggleAll = () => setSelected(allSelected ? new Set() : new Set(visibleIds)); + const toggleOne = (id: string) => { + const next = new Set(selected); + if (next.has(id)) next.delete(id); else next.add(id); + setSelected(next); + }; + + const bulkArchive = async (archived: boolean) => { + if (selected.size === 0) return; + setBusy(true); + const ids = Array.from(selected); + const { error } = await supabase + .from("cases") + .update({ archived_at: archived ? new Date().toISOString() : null }) + .in("id", ids); + setBusy(false); + if (error) toast.error(error.message); + else { + toast.success(`${ids.length} case(s) ${archived ? "archived" : "restored"}`); + setSelected(new Set()); + load(); + } + }; + + const bulkAssignAttorney = async () => { + if (selected.size === 0 || !assignAttorney) return; + setBusy(true); + const ids = Array.from(selected); + const { error } = await supabase.from("cases").update({ assigned_attorney_id: assignAttorney }).in("id", ids); + setBusy(false); + if (error) toast.error(error.message); + else { + toast.success(`${ids.length} case(s) reassigned`); + setSelected(new Set()); + setAssignAttorney(""); + load(); + } + }; + + const bulkAssignClient = async () => { + if (selected.size === 0 || !assignClient) return; + setBusy(true); + const ids = Array.from(selected); + const { error } = await supabase.from("cases").update({ client_id: assignClient }).in("id", ids); + setBusy(false); + if (error) toast.error(error.message); + else { + toast.success(`${ids.length} case(s) re-linked to client`); + setSelected(new Set()); + setAssignClient(""); + load(); + } + }; + + const userOptions = users.map((u) => ({ + value: u.id, + label: u.full_name || u.email || u.id, + keywords: `${u.full_name || ""} ${u.email || ""}`, + })); + const clientOptions = clientList.map((c) => ({ value: c.id, label: c.name, keywords: c.name })); + const SortHeader = ({ label, k, align = "left" }: { label: string; k: SortKey; align?: "left" | "right" }) => { const active = sortKey === k; const Icon = !active ? ArrowUpDown : sortDir === "asc" ? ArrowUp : ArrowDown;