From bd350efa3606c79bfc053b204024ab3ab9abb613 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 04:25:14 +0000 Subject: [PATCH 1/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/contacts.index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/contacts.index.tsx b/src/routes/contacts.index.tsx index 3fd9e7d..1ff6b45 100644 --- a/src/routes/contacts.index.tsx +++ b/src/routes/contacts.index.tsx @@ -43,6 +43,7 @@ function ContactsIndex() { const [open, setOpen] = useState(false); const [selected, setSelected] = useState>(new Set()); const [bulkType, setBulkType] = useState(""); + const [letter, setLetter] = useState("all"); const load = async () => { setLoading(true); From a106a38e9a6bccff9410fcc2e3be02ce782cec0c Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 04:25:29 +0000 Subject: [PATCH 2/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/contacts.index.tsx | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/routes/contacts.index.tsx b/src/routes/contacts.index.tsx index 1ff6b45..98bdce3 100644 --- a/src/routes/contacts.index.tsx +++ b/src/routes/contacts.index.tsx @@ -71,7 +71,12 @@ function ContactsIndex() { load(); }, []); - const filtered = useMemo(() => { + const letterOf = (name: string | null | undefined) => { + const ch = (name?.[0] ?? "#").toUpperCase(); + return /[A-Z]/.test(ch) ? ch : "#"; + }; + + const preLetterFiltered = useMemo(() => { const term = q.trim().toLowerCase(); return rows.filter((r) => { if (view === "archived" ? !r.archived_at : !!r.archived_at) return false; @@ -86,13 +91,26 @@ function ContactsIndex() { }); }, [rows, q, typeFilter, view]); + const letterCounts = useMemo(() => { + const counts: Record = { all: preLetterFiltered.length }; + for (const r of preLetterFiltered) { + const l = letterOf(r.name); + counts[l] = (counts[l] ?? 0) + 1; + } + return counts; + }, [preLetterFiltered]); + + const filtered = useMemo(() => { + if (letter === "all") return preLetterFiltered; + return preLetterFiltered.filter((r) => letterOf(r.name) === letter); + }, [preLetterFiltered, letter]); + const grouped = useMemo(() => { const map = new Map(); for (const r of filtered) { - const ch = (r.name?.[0] ?? "#").toUpperCase(); - const letter = /[A-Z]/.test(ch) ? ch : "#"; - if (!map.has(letter)) map.set(letter, []); - map.get(letter)!.push(r); + const l = letterOf(r.name); + if (!map.has(l)) map.set(l, []); + map.get(l)!.push(r); } return Array.from(map.entries()).sort(([a], [b]) => { if (a === "#") return 1; From 7db35d8556c5b297fe7b64f7982f5b986d107ffc Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 04:25:41 +0000 Subject: [PATCH 3/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/contacts.index.tsx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/routes/contacts.index.tsx b/src/routes/contacts.index.tsx index 98bdce3..5ce2e07 100644 --- a/src/routes/contacts.index.tsx +++ b/src/routes/contacts.index.tsx @@ -284,6 +284,33 @@ function ContactsIndex() { ))} +
+ + {"ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").concat("#").map((L) => { + const count = letterCounts[L] ?? 0; + const disabled = count === 0; + return ( + + ); + })} + {selected.size > 0 && ( From c3ebb21034ccb93cedbbf3efdb58c2aea0ec985d Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 04:25:53 +0000 Subject: [PATCH 4/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/contacts.index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/contacts.index.tsx b/src/routes/contacts.index.tsx index 5ce2e07..c011b16 100644 --- a/src/routes/contacts.index.tsx +++ b/src/routes/contacts.index.tsx @@ -310,6 +310,7 @@ function ContactsIndex() { ); })} +
{selected.size > 0 && (