'use client'; import { useState } from 'react'; import { clientApi } from '@/lib/client-api'; import { fmtDate } from '@/lib/format'; import type { ChangeEvent } from '@/lib/types'; import { ChangeRow, groupByDay } from './change-row'; /** * Cursor pagination for /changes: the server renders the first page; this appends more via `before=`. * `qs` carries the active filters (category, type, importance_min, since, include_backfill, date_field…). The cursor is * the API's `next_before` (1.1: follows `date_field`, `occurred_at` by default) — falls back to the last row's date. */ export function LoadMore({ qs, initialCursor, lastDay, dateField = 'occurred' }: { qs: string; initialCursor: string | null; lastDay: string | null; dateField?: 'occurred' | 'observed' }) { const [items, setItems] = useState([]); const [cursor, setCursor] = useState(initialCursor); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); const groups = groupByDay(items, dateField); const more = async () => { if (!cursor) return; setLoading(true); setError(false); try { const p = new URLSearchParams(qs); p.set('before', cursor); p.set('limit', '50'); const res = (await clientApi.changes(p.toString())) as Awaited> & { next_before?: string | null }; setItems((prev) => [...prev, ...res.items]); const last = res.items[res.items.length - 1]; const fallback = last ? (dateField === 'occurred' ? last.occurred_at ?? last.effective_at ?? last.observed_at : last.observed_at) : null; setCursor(res.items.length < 50 || !last ? null : res.next_before ?? fallback); } catch { setError(true); } finally { setLoading(false); } }; return ( <> {groups.map((g, i) => (
{(i > 0 || g.day !== lastDay) && (

{fmtDate(g.day)} {g.items.length}

)}
    {g.items.map((e) => ( ))}
))}
{cursor ? ( ) : (

End of the recorded history for these filters.

)} {error &&

Could not load more — try again.

}
); }