From 5c6eb2f913c7c8f0e41ad0358ccc45f294f49dbf Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sat, 14 Mar 2026 19:18:22 +0000 Subject: [PATCH 1/2] [#67] Add pagination to reader dashboard donation query Fixes #67 - Add .range() pagination with PAGE_SIZE=50 and Supabase count:"exact" for accurate total count without fetching all rows - Add prev/next page controls when more than one page exists - Total $PLOT display scoped to current page to avoid inaccurate sums Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/dashboard/reader/page.tsx | 65 +++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/src/app/dashboard/reader/page.tsx b/src/app/dashboard/reader/page.tsx index 56354378..1cb76d2d 100644 --- a/src/app/dashboard/reader/page.tsx +++ b/src/app/dashboard/reader/page.tsx @@ -1,31 +1,49 @@ "use client"; +import { useState } from "react"; import { useAccount } from "wagmi"; import { useQuery } from "@tanstack/react-query"; import { supabase, type Donation } from "../../../../lib/supabase"; import { ConnectWallet } from "../../../components/ConnectWallet"; import { formatUnits } from "viem"; -async function fetchDonations(address: string): Promise { - if (!supabase) return []; - const { data } = await supabase +const PAGE_SIZE = 50; + +interface DonationPage { + rows: Donation[]; + totalCount: number; +} + +async function fetchDonationPage( + address: string, + page: number, +): Promise { + if (!supabase) return { rows: [], totalCount: 0 }; + const from = page * PAGE_SIZE; + const to = from + PAGE_SIZE - 1; + const { data, count } = await supabase .from("donations") - .select("*") + .select("*", { count: "exact" }) .eq("donor_address", address.toLowerCase()) .order("block_timestamp", { ascending: false }) + .range(from, to) .returns(); - return data ?? []; + return { rows: data ?? [], totalCount: count ?? 0 }; } export default function ReaderDashboard() { const { address, isConnected } = useAccount(); + const [page, setPage] = useState(0); - const { data: donations = [], isLoading } = useQuery({ - queryKey: ["reader-donations", address], - queryFn: () => fetchDonations(address!), + const { data, isLoading } = useQuery({ + queryKey: ["reader-donations", address, page], + queryFn: () => fetchDonationPage(address!, page), enabled: isConnected && !!address, }); + const donations = data?.rows ?? []; + const totalCount = data?.totalCount ?? 0; + if (!isConnected) { return (
@@ -42,6 +60,10 @@ export default function ReaderDashboard() { BigInt(0), ); + const totalPages = Math.ceil(totalCount / PAGE_SIZE); + const hasMore = page + 1 < totalPages; + const hasPrev = page > 0; + return (

@@ -62,12 +84,11 @@ export default function ReaderDashboard() { Donation History

- {donations.length}{" "} - {donations.length === 1 ? "donation" : "donations"} + {totalCount} {totalCount === 1 ? "donation" : "donations"} {donations.length > 0 && ( {" "} - · {formatUnits(totalDonated, 18)} $PLOT total + · {formatUnits(totalDonated, 18)} $PLOT on this page )}

@@ -84,6 +105,28 @@ export default function ReaderDashboard() {

)}
+ + {totalPages > 1 && ( +
+ + + Page {page + 1} of {totalPages} + + +
+ )}
); From 96aa28cc14479a39f134a0105e04e09e813be88b Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sat, 14 Mar 2026 19:21:32 +0000 Subject: [PATCH 2/2] [#67] Reset page to 0 on wallet address change Prevents stale page index from showing false empty state when switching to a wallet with fewer donations. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/dashboard/reader/page.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/dashboard/reader/page.tsx b/src/app/dashboard/reader/page.tsx index 1cb76d2d..7e942456 100644 --- a/src/app/dashboard/reader/page.tsx +++ b/src/app/dashboard/reader/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useAccount } from "wagmi"; import { useQuery } from "@tanstack/react-query"; import { supabase, type Donation } from "../../../../lib/supabase"; @@ -35,6 +35,11 @@ export default function ReaderDashboard() { const { address, isConnected } = useAccount(); const [page, setPage] = useState(0); + // Reset to first page when wallet address changes + useEffect(() => { + setPage(0); + }, [address]); + const { data, isLoading } = useQuery({ queryKey: ["reader-donations", address, page], queryFn: () => fetchDonationPage(address!, page),