frontend: date range picker on Incidents and Archive; fix Archive paging

Incidents and Archive get a from/to date range (native date inputs,
local-day bounds). Incidents filters in the Firestore query; Archive
passes date_from/date_to to GET /calls/search, which applies them as a
started_at range — both ride the existing org_id/started_at index.

Also fixes /calls/search and /calls/eval-queue paging: the cursor went to
Firestore as a raw ISO string against a timestamp field, which compares
by type rather than time, so "Load more" re-read the first page. Cursor
and range bounds are now parsed to datetimes (400 on garbage).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Logan Cusano
2026-09-24 01:03:40 -04:00
co-authored by Claude Opus 5.5
parent c043298902
commit 6479174022
7 changed files with 161 additions and 11 deletions
+9 -2
View File
@@ -11,7 +11,7 @@ const toISO = (v: unknown): string =>
(v as { toDate?: () => Date })?.toDate?.()?.toISOString?.() ??
(typeof v === "string" ? v : new Date().toISOString());
export function useIncidents(limitCount = 100) {
export function useIncidents(limitCount = 100, dateFrom?: Date, dateTo?: Date) {
const [incidents, setIncidents] = useState<IncidentRecord[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@@ -20,6 +20,10 @@ export function useIncidents(limitCount = 100) {
const [hasMore, setHasMore] = useState(false);
const { orgId } = useAuth();
// 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;
@@ -37,9 +41,12 @@ export function useIncidents(limitCount = 100) {
return;
}
// A range on the ordered field rides the existing org_id/started_at index.
const q = query(
collection(db, "incidents"),
where("org_id", "==", orgId),
...(dateFromMs != null ? [where("started_at", ">=", new Date(dateFromMs))] : []),
...(dateToMs != null ? [where("started_at", "<=", new Date(dateToMs))] : []),
orderBy("started_at", "desc"),
limit(limitCount)
);
@@ -65,7 +72,7 @@ export function useIncidents(limitCount = 100) {
unsubAuth();
if (unsubFirestore) unsubFirestore();
};
}, [limitCount, orgId]);
}, [limitCount, dateFromMs, dateToMs, orgId]);
return { incidents, loading, error, hasMore };
}