Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 93 lines 2.6 kB view raw
1import { GiftIcon } from "@heroicons/react/24/outline"; 2import { BLOCK_EXPLORER_URL } from "@hey/data/constants"; 3import { 4 PageSize, 5 type TokenDistributionsRequest, 6 useTokenDistributionsQuery 7} from "@hey/indexer"; 8import dayjs from "dayjs"; 9import { useCallback } from "react"; 10import { Link } from "react-router"; 11import { WindowVirtualizer } from "virtua"; 12import Loader from "@/components/Shared/Loader"; 13import { EmptyState, ErrorMessage } from "@/components/Shared/UI"; 14import useLoadMoreOnIntersect from "@/hooks/useLoadMoreOnIntersect"; 15 16const List = () => { 17 const request: TokenDistributionsRequest = { 18 pageSize: PageSize.Fifty 19 }; 20 21 const { data, error, fetchMore, loading } = useTokenDistributionsQuery({ 22 variables: { request } 23 }); 24 25 const tokenRewards = data?.tokenDistributions?.items; 26 const pageInfo = data?.tokenDistributions?.pageInfo; 27 const hasMore = pageInfo?.next; 28 29 const handleEndReached = useCallback(async () => { 30 if (hasMore) { 31 await fetchMore({ 32 variables: { request: { ...request, cursor: pageInfo?.next } } 33 }); 34 } 35 }, [fetchMore, hasMore, pageInfo?.next, request]); 36 37 const loadMoreRef = useLoadMoreOnIntersect(handleEndReached); 38 39 if (loading) { 40 return <Loader className="my-10" />; 41 } 42 43 if (!tokenRewards?.length) { 44 return ( 45 <EmptyState 46 hideCard 47 icon={<GiftIcon className="size-8" />} 48 message="You haven't received any rewards yet." 49 /> 50 ); 51 } 52 53 if (error) { 54 return ( 55 <ErrorMessage 56 className="m-5" 57 error={error} 58 title="Failed to load rewards" 59 /> 60 ); 61 } 62 63 return ( 64 <div className="virtual-divider-list-window"> 65 <WindowVirtualizer> 66 {tokenRewards.map((distribution) => ( 67 <div 68 className="flex items-center justify-between p-5" 69 key={distribution.txHash} 70 > 71 <div className="flex items-center space-x-2"> 72 <GiftIcon className="size-4 text-gray-500 dark:text-gray-200" /> 73 <div> 74 Received <b>{Number(distribution.amount.value).toFixed(4)}</b> 75 </div> 76 </div> 77 <Link 78 className="text-gray-500 text-sm dark:text-gray-200" 79 rel="noreferrer noopener" 80 target="_blank" 81 to={`${BLOCK_EXPLORER_URL}/tx/${distribution.txHash}`} 82 > 83 {dayjs(distribution.timestamp).format("MMM D, YYYY h:mm A")} 84 </Link> 85 </div> 86 ))} 87 {hasMore && <span ref={loadMoreRef} />} 88 </WindowVirtualizer> 89 </div> 90 ); 91}; 92 93export default List;