From 9cf8fd4221d348c24649a63ed059056f14c7b951 Mon Sep 17 00:00:00 2001 From: Logan Date: Sat, 23 May 2026 13:28:23 -0400 Subject: [PATCH] fix date filter --- drb-frontend/app/calls/page.tsx | 19 ++++++++----------- drb-frontend/lib/useCalls.ts | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/drb-frontend/app/calls/page.tsx b/drb-frontend/app/calls/page.tsx index a264b6c..3fff239 100644 --- a/drb-frontend/app/calls/page.tsx +++ b/drb-frontend/app/calls/page.tsx @@ -12,10 +12,8 @@ const inputCls = "placeholder:text-gray-600 focus:outline-none focus:border-indigo-500 w-full"; function filterCalls(calls: CallRecord[], filters: Filters): CallRecord[] { - const q = filters.query.trim().toLowerCase(); - const tgid = filters.tgid.trim(); - const fromMs = filters.dateFrom ? new Date(filters.dateFrom + "T00:00:00").getTime() : null; - const toMs = filters.dateTo ? new Date(filters.dateTo + "T23:59:59").getTime() : null; + const q = filters.query.trim().toLowerCase(); + const tgid = filters.tgid.trim(); return calls.filter((c) => { // System filter @@ -24,11 +22,6 @@ function filterCalls(calls: CallRecord[], filters: Filters): CallRecord[] { // TGID filter (exact match on the number) if (tgid && String(c.talkgroup_id ?? "") !== tgid) return false; - // Date range - const ts = new Date(c.started_at).getTime(); - if (fromMs !== null && ts < fromMs) return false; - if (toMs !== null && ts > toMs) return false; - // Free-text: talkgroup name, node_id, transcript, tags if (q) { const hay = [ @@ -67,12 +60,16 @@ function isActive(f: Filters) { export default function CallsPage() { const [limitCount, setLimitCount] = useState(100); - const { calls, loading } = useCalls(limitCount); + const [filters, setFilters] = useState(DEFAULT_FILTERS); + + const dateFrom = filters.dateFrom ? new Date(filters.dateFrom + "T00:00:00") : undefined; + const dateTo = filters.dateTo ? new Date(filters.dateTo + "T23:59:59") : undefined; + + const { calls, loading } = useCalls(limitCount, dateFrom, dateTo); const { systems } = useSystems(); const { isAdmin } = useAuth(); const systemMap = Object.fromEntries(systems.map((s) => [s.system_id, s])); - const [filters, setFilters] = useState(DEFAULT_FILTERS); const [showFilters, setShowFilters] = useState(false); function set(key: K, value: string) { diff --git a/drb-frontend/lib/useCalls.ts b/drb-frontend/lib/useCalls.ts index c192f23..e118da6 100644 --- a/drb-frontend/lib/useCalls.ts +++ b/drb-frontend/lib/useCalls.ts @@ -6,11 +6,15 @@ import { onAuthStateChanged } from "firebase/auth"; import { db, auth } from "@/lib/firebase"; import type { CallRecord } from "@/lib/types"; -export function useCalls(limitCount = 50) { +export function useCalls(limitCount = 50, dateFrom?: Date, dateTo?: Date) { const [calls, setCalls] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + // Stable ms values so the effect dependency doesn't fire on every render + const dateFromMs = dateFrom?.getTime(); + const dateToMs = dateTo?.getTime(); + useEffect(() => { let unsubFirestore: (() => void) | undefined; @@ -23,11 +27,16 @@ export function useCalls(limitCount = 50) { return; } - const q = query( - collection(db, "calls"), + const from = dateFromMs != null ? new Date(dateFromMs) : undefined; + const to = dateToMs != null ? new Date(dateToMs) : undefined; + + const constraints = [ + ...(from ? [where("started_at", ">=", from)] : []), + ...(to ? [where("started_at", "<=", to)] : []), orderBy("started_at", "desc"), - limit(limitCount) - ); + limit(limitCount), + ]; + const q = query(collection(db, "calls"), ...constraints); const toISO = (v: any): string | null => v?.toDate?.()?.toISOString?.() ?? (typeof v === "string" ? v : null); unsubFirestore = onSnapshot(q, (snap) => { @@ -43,7 +52,7 @@ export function useCalls(limitCount = 50) { unsubAuth(); if (unsubFirestore) unsubFirestore(); }; - }, [limitCount]); + }, [limitCount, dateFromMs, dateToMs]); return { calls, loading, error }; }