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
+8 -1
View File
@@ -24,6 +24,7 @@ import { Button } from "@/components/ui/Button";
import { EmptyState, ErrorBanner } from "@/components/ui/EmptyState";
import { SkeletonCard } from "@/components/ui/Skeleton";
import { MachineOutputNotice } from "@/components/ui/MachineOutputNotice";
import { DateRange, dayStart, dayEnd } from "@/components/ui/DateRange";
type LinkFilter = "any" | "orphan" | "linked";
type TranscriptFilter = "any" | "yes" | "no";
@@ -239,6 +240,8 @@ export default function ArchivePage() {
const [systemId, setSystemId] = useState("");
const [q, setQ] = useState("");
const [submittedQ, setSubmittedQ] = useState("");
const [dateFrom, setDateFrom] = useState("");
const [dateTo, setDateTo] = useState("");
useEffect(() => {
if (!authLoading && !canView) router.replace("/");
@@ -256,6 +259,8 @@ export default function ArchivePage() {
transcript,
system_id: systemId || undefined,
q: submittedQ || undefined,
date_from: dayStart(dateFrom)?.toISOString(),
date_to: dayEnd(dateTo)?.toISOString(),
});
setCalls((prev) => (append ? [...prev, ...res.calls] : res.calls));
setCursor(res.next_cursor);
@@ -266,7 +271,7 @@ export default function ArchivePage() {
setLoading(false);
}
},
[link, transcript, systemId, submittedQ],
[link, transcript, systemId, submittedQ, dateFrom, dateTo],
);
// Reload from the top whenever a filter changes.
@@ -335,6 +340,8 @@ export default function ArchivePage() {
))}
</select>
<DateRange from={dateFrom} to={dateTo} onChange={(f, t) => { setDateFrom(f); setDateTo(t); }} />
<form
onSubmit={(e) => { e.preventDefault(); setSubmittedQ(q.trim()); }}
className="flex items-center gap-2 ml-auto"