From a0e6d3787bd9c3f27b038656cc3299f52a2ffcc3 Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Sat, 24 Apr 2021 11:31:55 -0500 Subject: [PATCH 1/7] Updated fetchAllOffers and queryAllOffers for pagination params --- contexts/graph/index.tsx | 6 ++++-- contexts/graph/queries.ts | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/contexts/graph/index.tsx b/contexts/graph/index.tsx index bae3e50..e2152b0 100644 --- a/contexts/graph/index.tsx +++ b/contexts/graph/index.tsx @@ -100,11 +100,13 @@ export const GraphProvider: React.FC = ({ children }) => { const fetchAllOffers = async ( take: number, - skip: number + skip: number, + orderBy: string = null, + orderDirection: string = null, ): Promise => { setDataLoading(false); if (!currentAddress) return; - const query = queryAllOffers(take, skip); + const query = queryAllOffers(take, skip, orderBy, orderDirection); const subgraphURI = ENDPOINT_MOONCAT_PROD; const response: { offerPrices: AdoptionOffer[]; diff --git a/contexts/graph/queries.ts b/contexts/graph/queries.ts index 1ce78a8..c1922a2 100644 --- a/contexts/graph/queries.ts +++ b/contexts/graph/queries.ts @@ -131,9 +131,9 @@ export const queryAllRequests = (): string => { }`; }; -export const queryAllOffers = (first: number, skip: number): string => { +export const queryAllOffers = (first: number, skip: number, orderBy: string = null, orderDirection: string = null): string => { return `{ - offerPrices(where: {active_in: [true]}, first: ${first}, skip: ${skip}) { + offerPrices(where: {active_in: [true]}, first: ${first}, skip: ${skip}, orderBy: ${orderBy}, orderDirection: ${orderDirection}) { id price to From ede17fe070f4b7620a87c8b7f9024928a929ce25 Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Sat, 24 Apr 2021 11:32:10 -0500 Subject: [PATCH 2/7] Added disabled style for button --- styles/layout.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/styles/layout.scss b/styles/layout.scss index cb859aa..3a74b0a 100644 --- a/styles/layout.scss +++ b/styles/layout.scss @@ -541,6 +541,12 @@ 2px 2px 0 #8349be, 1px 1px 0 #8349be; } + &:disabled { + background: gray; + box-shadow: 5px 5px 0 gray, 4px 4px 0 gray, 3px 3px 0 gray, + 2px 2px 0 gray, 1px 1px 0 gray; + } + &__active { background: #fc9706; box-shadow: 5px 5px 0 #f58901, 4px 4px 0 #f58901, 3px 3px 0 #f58901, From 0567a5576d0bf7cff29bf880a93c093396ca6a83 Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Sat, 24 Apr 2021 11:32:23 -0500 Subject: [PATCH 3/7] Integrated pagination feature for offers page --- pages/offered/index.tsx | 173 ++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 69 deletions(-) diff --git a/pages/offered/index.tsx b/pages/offered/index.tsx index 2ae1731..7fbbc35 100644 --- a/pages/offered/index.tsx +++ b/pages/offered/index.tsx @@ -2,7 +2,7 @@ import request from 'graphql-request'; import Head from 'next/head'; import React, { useState, useCallback, useContext, useMemo } from 'react'; import { ethers } from 'ethers'; -import { calculatePrice, getDateTime } from '../../utils'; +import { calculatePrice } from '../../utils'; import GraphContext from '../../contexts/graph/index'; import { Cat, AdoptionOffer } from '../../contexts/graph/types'; @@ -16,7 +16,6 @@ import Loader from '../../components/ui/loader'; import { queryAllOffers } from '../../contexts/graph/queries'; import { ENDPOINT_MOONCAT_PROD, - FETCH_ALL_OFFERS_TAKE, FETCH_EVERY_OFFERS_TAKE, } from '../../lib/consts'; import { GetStaticProps } from 'next'; @@ -28,6 +27,11 @@ enum OffereSortType { OLDEST = 'OLDEST', } +enum NavigateType { + PREV = 'NAVIGATE_PREV', + NEXT = 'NAVIGATE_NEXT', +} + const sortTypes: Record = { [OffereSortType.HIGH_PRICE]: 'HIGH PRICE', [OffereSortType.CHEAPEST]: 'CHEAPEST', @@ -35,28 +39,16 @@ const sortTypes: Record = { [OffereSortType.OLDEST]: 'OLDEST', }; -const sortFn: Record< - OffereSortType, - (offerA: AdoptionOffer, offerB: AdoptionOffer) => number -> = { - [OffereSortType.HIGH_PRICE]: ( - offerA: AdoptionOffer, - offerB: AdoptionOffer - ) => { - return parseInt(offerB.price, 10) - parseInt(offerA.price, 10); - }, - [OffereSortType.CHEAPEST]: (offerA: AdoptionOffer, offerB: AdoptionOffer) => { - return parseInt(offerA.price, 10) - parseInt(offerB.price, 10); - }, - [OffereSortType.RECENTLY_LISTED]: ( - offerA: AdoptionOffer, - offerB: AdoptionOffer - ) => { - return getDateTime(offerB.timestamp) - getDateTime(offerA.timestamp); - }, - [OffereSortType.OLDEST]: (offerA: AdoptionOffer, offerB: AdoptionOffer) => - getDateTime(offerA.timestamp) - getDateTime(offerB.timestamp), -}; +const getOrderByParam = (sortType: OffereSortType) => + sortType === OffereSortType.CHEAPEST || sortType === OffereSortType.HIGH_PRICE + ? 'price' + : 'timestamp'; + +const getOrderDirectionParam = (sortType: OffereSortType) => + sortType === OffereSortType.HIGH_PRICE || + sortType === OffereSortType.RECENTLY_LISTED + ? 'desc' + : 'asc'; const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ allOffers: ssrOffers, @@ -67,9 +59,7 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ // State const [allOffers, setAllOffers] = useState(ssrOffers); - const [currentSkipCount, setCurrentSkipCount] = useState( - FETCH_ALL_OFFERS_TAKE - ); + const [currentSkipCount, setCurrentSkipCount] = useState(0); const [error, setError] = useState(); const [isLoading, setIsLoading] = useState(false); const [isOpenModal, setOpenModal] = useState(false); @@ -80,27 +70,54 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ const [isCopiedSuccessfully, setIsCopiedSuccessfully] = useState( false ); + const [disableNext, setDisableNext] = useState(false); // Memoized values - const sortedOffer = useMemo(() => { - return allOffers.sort(sortFn[currentSortType]); - }, [currentSortType, allOffers]); + const filteredOffers = useMemo(() => { + return disableNext ? allOffers : allOffers.slice(0, allOffers.length - 1); + }, [disableNext, allOffers]); // Callbacks - const handleFetchOffers = useCallback(async () => { + const handleFetchOffers = useCallback( + async (navigateType: NavigateType) => { + setIsLoading(true); + const offers = await fetchAllOffers( + FETCH_EVERY_OFFERS_TAKE + 1, + currentSkipCount + + (navigateType === NavigateType.NEXT ? 1 : -1) * + FETCH_EVERY_OFFERS_TAKE, + getOrderByParam(currentSortType), + getOrderDirectionParam(currentSortType) + ); + setCurrentSkipCount( + (prevSkip) => + prevSkip + + (navigateType === NavigateType.NEXT ? 1 : -1) * + FETCH_EVERY_OFFERS_TAKE + ); + setAllOffers(() => [...offers]); + setIsLoading(false); + if (offers.length !== FETCH_EVERY_OFFERS_TAKE + 1) setDisableNext(true); + else setDisableNext(false); + }, + [currentSkipCount, fetchAllOffers] + ); + + const handleSort = async (sortType: OffereSortType) => { setIsLoading(true); - const yOffset = window.pageYOffset + 100; const offers = await fetchAllOffers( - FETCH_EVERY_OFFERS_TAKE, - currentSkipCount + FETCH_EVERY_OFFERS_TAKE + 1, + 0, + getOrderByParam(currentSortType), + getOrderDirectionParam(currentSortType) ); - setCurrentSkipCount((prevSkip) => prevSkip + FETCH_EVERY_OFFERS_TAKE); - setAllOffers((prevOffers) => [...prevOffers, ...offers]); + + setCurrentSkipCount(0); + setAllOffers(() => [...offers]); setIsLoading(false); - window.scrollTo(0, yOffset); - }, [currentSkipCount, fetchAllOffers]); + setCurrentSortType(sortType); + }; - const handleSort = (sortType: OffereSortType) => setCurrentSortType(sortType); const handleModalClose = useCallback(() => setOpenModal(false), []); const handleModalOpen = useCallback((offer: AdoptionOffer) => { setError(undefined); @@ -155,38 +172,51 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ -
- {sortedOffer.map((offer) => { - const catId = offer.id.split('::')[0]; - return ( - -
- -
-
- ); - })} -
+ {!isLoading && ( +
+ {filteredOffers.map((offer) => { + const catId = offer.id.split('::')[0]; + return ( + +
+ +
+
+ ); + })} +
+ )} {isCopiedSuccessfully && } {!isLoading ? (
- +
) : ( @@ -212,7 +242,12 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ }; export const getStaticProps: GetStaticProps = async () => { - const offeredQuery = queryAllOffers(FETCH_ALL_OFFERS_TAKE, 0); + const offeredQuery = queryAllOffers( + FETCH_EVERY_OFFERS_TAKE + 1, + 0, + 'timestamp', + 'desc' + ); const { offerPrices: allOffers } = await request( ENDPOINT_MOONCAT_PROD, offeredQuery From fd63c2d65e6db0c9df565a2b15606b6c18c18a85 Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Mon, 26 Apr 2021 21:21:10 -0500 Subject: [PATCH 4/7] Updated GraphContextType for fetchAllOffers --- contexts/graph/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contexts/graph/index.tsx b/contexts/graph/index.tsx index e2152b0..93e64dc 100644 --- a/contexts/graph/index.tsx +++ b/contexts/graph/index.tsx @@ -24,7 +24,9 @@ type GraphContextType = { fetchMyMoonCats(): Promise; fetchAllOffers( take: number, - skip: number + skip: number, + orderBy: string, + orderDirection: string ): Promise; }; @@ -102,7 +104,7 @@ export const GraphProvider: React.FC = ({ children }) => { take: number, skip: number, orderBy: string = null, - orderDirection: string = null, + orderDirection: string = null ): Promise => { setDataLoading(false); if (!currentAddress) return; From ca424644031bea89dad0eb9e4e3f9bc833c72429 Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Mon, 26 Apr 2021 21:21:54 -0500 Subject: [PATCH 5/7] Prettified queryAllOffers --- contexts/graph/queries.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contexts/graph/queries.ts b/contexts/graph/queries.ts index c1922a2..001d9a9 100644 --- a/contexts/graph/queries.ts +++ b/contexts/graph/queries.ts @@ -131,7 +131,12 @@ export const queryAllRequests = (): string => { }`; }; -export const queryAllOffers = (first: number, skip: number, orderBy: string = null, orderDirection: string = null): string => { +export const queryAllOffers = ( + first: number, + skip: number, + orderBy: string = null, + orderDirection: string = null +): string => { return `{ offerPrices(where: {active_in: [true]}, first: ${first}, skip: ${skip}, orderBy: ${orderBy}, orderDirection: ${orderDirection}) { id From 22bd2a43f244287029abbe06dc8cc41221f98710 Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Mon, 26 Apr 2021 21:22:17 -0500 Subject: [PATCH 6/7] Fixed wrong param passing for sort feature --- pages/offered/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/offered/index.tsx b/pages/offered/index.tsx index 7fbbc35..108fb6a 100644 --- a/pages/offered/index.tsx +++ b/pages/offered/index.tsx @@ -100,7 +100,7 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ if (offers.length !== FETCH_EVERY_OFFERS_TAKE + 1) setDisableNext(true); else setDisableNext(false); }, - [currentSkipCount, fetchAllOffers] + [currentSkipCount, fetchAllOffers, currentSortType] ); const handleSort = async (sortType: OffereSortType) => { @@ -108,8 +108,8 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ const offers = await fetchAllOffers( FETCH_EVERY_OFFERS_TAKE + 1, 0, - getOrderByParam(currentSortType), - getOrderDirectionParam(currentSortType) + getOrderByParam(sortType), + getOrderDirectionParam(sortType) ); setCurrentSkipCount(0); From 667da98e13f9d6c0f259899f98062154fb2db50b Mon Sep 17 00:00:00 2001 From: ace-contributor Date: Mon, 3 May 2021 21:05:14 -0500 Subject: [PATCH 7/7] Added filter for fetchedOffers --- pages/offered/index.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pages/offered/index.tsx b/pages/offered/index.tsx index 108fb6a..3cb6e6e 100644 --- a/pages/offered/index.tsx +++ b/pages/offered/index.tsx @@ -74,7 +74,13 @@ const OfferedCats: React.FC<{ allOffers: AdoptionOffer[] }> = ({ // Memoized values const filteredOffers = useMemo(() => { - return disableNext ? allOffers : allOffers.slice(0, allOffers.length - 1); + return (disableNext + ? allOffers + : allOffers.slice(0, allOffers.length - 1) + ).filter( + (offer: AdoptionOffer) => + offer.to.toLowerCase() == ethers.constants.AddressZero + ); }, [disableNext, allOffers]); // Callbacks