From 9c4a96fe977b7a0907f5dea99491385195b76184 Mon Sep 17 00:00:00 2001 From: Paul Nothaft Date: Sun, 10 May 2026 21:18:10 +0200 Subject: [PATCH] fix(events): clamp page state when totalPages drops below current page (#442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bulk-deleting all events on the current page left the list empty until manual reload. After the React Query refetch returned `events: []` with a smaller `totalPages`, the page state was stuck on the old (now out-of-range) page index — the backend correctly serves an empty page for `page > totalPages`, but the UI had no logic to step back. Add a useEffect that watches `data.pagination.totalPages` against the current `page` and resets `page = max(1, totalPages)` whenever the result count shrinks. Fires after every refetch so it covers bulk delete, individual delete, archive, and any filter change that shrinks the result set — same one-line guarantee. Reported by @Rekoo-PS in #442. --- frontend/src/pages/admin/EventsListPage.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/src/pages/admin/EventsListPage.tsx b/frontend/src/pages/admin/EventsListPage.tsx index 61d03fbb..0b8b293a 100644 --- a/frontend/src/pages/admin/EventsListPage.tsx +++ b/frontend/src/pages/admin/EventsListPage.tsx @@ -104,6 +104,17 @@ export const EventsListPage: React.FC = () => { setPage(1); }, [statusFilter, debouncedSearchTerm]); + // Clamp the active page when the result count shrinks (#442 — bulk + // delete of an entire page would leave the user on a now-empty + // page=N where N > totalPages, with no auto-correction). Triggers + // after each successful refetch when totalPages drops below the + // current page (bulk delete, individual delete, archive, anything). + useEffect(() => { + if (data?.pagination && page > data.pagination.totalPages) { + setPage(Math.max(1, data.pagination.totalPages)); + } + }, [data?.pagination, page]); + // Close dropdown when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => {