diff --git a/src/app/dashboard/writer/page.tsx b/src/app/dashboard/writer/page.tsx index 02cd0570..88b7c385 100644 --- a/src/app/dashboard/writer/page.tsx +++ b/src/app/dashboard/writer/page.tsx @@ -4,15 +4,17 @@ import { useState } from "react"; import { useAccount, useSignMessage } from "wagmi"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { formatUnits } from "viem"; -import { supabase, type Storyline } from "../../../../lib/supabase"; +import { supabase, type Storyline, type Donation } from "../../../../lib/supabase"; import { getTokenTVL } from "../../../../lib/price"; -import { RESERVE_LABEL, STORY_FACTORY } from "../../../../lib/contracts/constants"; +import { RESERVE_LABEL, STORY_FACTORY, EXPLORER_URL } from "../../../../lib/contracts/constants"; import { GENRES, LANGUAGES } from "../../../../lib/genres"; import { DeadlineCountdown } from "../../../components/DeadlineCountdown"; import { ClaimRoyalties } from "../../../components/ClaimRoyalties"; import { WriterTradingStats } from "../../../components/WriterTradingStats"; import { WriterIdentityClient } from "../../../components/WriterIdentityClient"; import { DropdownSelect } from "../../../components/DropdownSelect"; +import { truncateAddress } from "../../../../lib/utils"; +import { formatPrice } from "../../../../lib/format"; import Link from "next/link"; import { ConnectWallet } from "../../../components/ConnectWallet"; import { type Address } from "viem"; @@ -177,6 +179,90 @@ function StorylineDetail({ storyline, writerAddress }: { storyline: Storyline; w /> )} + + + + ); +} + +const DONATION_PAGE_SIZE = 10; + +function WriterDonationHistory({ storylineId }: { storylineId: number }) { + const [limit, setLimit] = useState(DONATION_PAGE_SIZE); + + const { data } = useQuery({ + queryKey: ["writer-donations", storylineId, limit], + queryFn: async () => { + if (!supabase) return { rows: [], totalCount: 0 }; + const { data: rows, count } = await supabase + .from("donations") + .select("*", { count: "exact" }) + .eq("storyline_id", storylineId) + .eq("contract_address", STORY_FACTORY.toLowerCase()) + .order("block_timestamp", { ascending: false }) + .range(0, limit - 1) + .returns(); + return { rows: rows ?? [], totalCount: count ?? 0 }; + }, + }); + + const donations = data?.rows ?? []; + const totalCount = data?.totalCount ?? 0; + const hasMore = donations.length < totalCount; + + if (donations.length === 0) return null; + + return ( + + + Donation History + + + {donations.map((d) => ( + + + + {truncateAddress(d.donor_address)} + + {d.block_timestamp && ( + + {new Date(d.block_timestamp).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + })} + + )} + + + + {formatPrice(formatUnits(BigInt(d.amount), 18))} {RESERVE_LABEL} + + {d.tx_hash && ( + + ↗ + + )} + + + ))} + + {hasMore && ( + setLimit((l) => l + DONATION_PAGE_SIZE)} + className="text-accent hover:text-foreground mt-2 w-full text-center text-[10px] transition-colors" + > + Load more ({totalCount - donations.length} remaining) + + )} ); }