fix: make Verification Management pagination actually work
All checks were successful
build-and-release / build (push) Successful in 1m3s

The page/next/prev controls were static markup with no onClick handlers,
and the "Showing X-Y of Z" label always rendered the same number for X, Y,
and Z (all displayRows().length) - pagination never did anything, all
fetched rows rendered on one page. Wires it to a real page signal with
working prev/next/page-number buttons, resets to page 1 when filters
change, and fixes the range label.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Ashwin Kumar Sivakumar 2026-07-19 19:41:39 +05:30
parent b208b37845
commit fadb2c0a80

View file

@ -1,5 +1,7 @@
import { A } from '@solidjs/router';
import { For, Show, createMemo, createSignal, onMount } from 'solid-js';
import { For, Show, createEffect, createMemo, createSignal, on, onMount } from 'solid-js';
const PAGE_SIZE = 20;
type VerificationStatus = 'PENDING' | 'UNDER_REVIEW' | 'DOCUMENTS_REQUESTED' | 'REVISION_REQUESTED' | 'APPROVED' | 'REJECTED';
type VerificationPriority = 'HIGH' | 'MEDIUM' | 'LOW';
@ -154,6 +156,7 @@ export default function VerificationManagementPage() {
const [docSelection, setDocSelection] = createSignal<Record<string, boolean>>({});
const [requestNote, setRequestNote] = createSignal('');
const [actionMessage, setActionMessage] = createSignal('');
const [page, setPage] = createSignal(1);
const load = async () => {
try {
@ -256,8 +259,33 @@ export default function VerificationManagementPage() {
return next;
});
const totalPages = createMemo(() => Math.max(1, Math.ceil(filteredRows().length / PAGE_SIZE)));
// Reset to page 1 whenever the underlying result set changes shape (search,
// status/category filters, sort) - otherwise a filter change can strand the
// user on a page number that no longer has any rows.
createEffect(on([search, statusFilter, categoryTab, sortBy], () => {
setPage(1);
}, { defer: true }));
createEffect(() => {
if (page() > totalPages()) setPage(totalPages());
});
const displayRows = createMemo(() => {
return filteredRows();
const start = (page() - 1) * PAGE_SIZE;
return filteredRows().slice(start, start + PAGE_SIZE);
});
const pageNumbers = createMemo(() => {
const total = totalPages();
const current = page();
const window = 2;
const nums: number[] = [];
for (let n = Math.max(1, current - window); n <= Math.min(total, current + window); n++) {
nums.push(n);
}
return nums;
});
const metrics = createMemo(() => {
@ -762,14 +790,32 @@ export default function VerificationManagementPage() {
<Show when={displayRows().length > 0}>
<div style="display:flex;align-items:center;justify-content:space-between;border-top:1px solid #F3F4F6;padding:12px 20px">
<p style="font-size:13px;color:#6B7280">
Showing <strong style="font-weight:600;color:#111827">1{displayRows().length}</strong> of <strong style="font-weight:600;color:#111827">{displayRows().length}</strong> verifications
Showing <strong style="font-weight:600;color:#111827">{(page() - 1) * PAGE_SIZE + 1}{(page() - 1) * PAGE_SIZE + displayRows().length}</strong> of <strong style="font-weight:600;color:#111827">{filteredRows().length}</strong> verifications
</p>
<div style="display:flex;align-items:center;gap:4px">
<button type="button" style="display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#6B7280;cursor:pointer;font-size:15px"></button>
<button type="button" style="display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;background:#FF5E13;color:white;font-size:13px;font-weight:600;border:none;cursor:pointer">1</button>
<button type="button" style="display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#374151;font-size:13px;font-weight:500;cursor:pointer">2</button>
<button type="button" style="display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#374151;font-size:13px;font-weight:500;cursor:pointer">3</button>
<button type="button" style="display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#6B7280;cursor:pointer;font-size:15px"></button>
<button
type="button"
disabled={page() === 1}
onClick={() => setPage((p) => Math.max(1, p - 1))}
style={`display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#6B7280;font-size:15px;${page() === 1 ? 'opacity:0.4;cursor:not-allowed' : 'cursor:pointer'}`}
></button>
<For each={pageNumbers()}>
{(n) => (
<button
type="button"
onClick={() => setPage(n)}
style={n === page()
? "display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;background:#FF5E13;color:white;font-size:13px;font-weight:600;border:none;cursor:pointer"
: "display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#374151;font-size:13px;font-weight:500;cursor:pointer"}
>{n}</button>
)}
</For>
<button
type="button"
disabled={page() === totalPages()}
onClick={() => setPage((p) => Math.min(totalPages(), p + 1))}
style={`display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border-radius:7px;border:1px solid #E5E7EB;background:white;color:#6B7280;font-size:15px;${page() === totalPages() ? 'opacity:0.4;cursor:not-allowed' : 'cursor:pointer'}`}
></button>
</div>
</div>
</Show>