Skip to content

Commit e97d112

Browse files
committed
fix: pagination repeating
1 parent d4324bd commit e97d112

File tree

6 files changed

+67
-27
lines changed

6 files changed

+67
-27
lines changed

src/api/services/exchangeRequestService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const submitExchangeRequest = async (requests: Map<number, CreateRequestData>, u
4646
const retrieveMarketplaceRequest = async (url: string): Promise<MarketplaceRequest[]> => {
4747
return fetch(url).then(async (res) => {
4848
const json = await res.json();
49-
return json.data;
49+
return json;
5050
}).catch((e) => {
5151
console.error(e);
5252
return [];

src/components/exchange/requests/issue/CustomizeRequest.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const CustomizeRequest = ({
3333
const [submittingRequest, setSubmittingRequest] = useState<boolean>(false);
3434
const [previewingForm, setPreviewingForm] = useState<boolean>(false);
3535

36+
3637
const submitRequest = async (urgentMessage: string) => {
3738
setSubmittingRequest(true);
3839
const res = await exchangeRequestService.submitExchangeRequest(requests, urgentMessage);

src/components/exchange/requests/view/ViewRequests.tsx

+49-23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PlusIcon } from "@heroicons/react/24/outline";
2-
import { Dispatch, SetStateAction, useContext, useEffect, useRef, useState } from "react";
2+
import { Dispatch, SetStateAction, useContext, useRef, useState } from "react";
33
import { DirectExchangeRequest, MarketplaceRequest } from "../../../../@types";
44
import ScheduleContext from "../../../../contexts/ScheduleContext";
55
import useMarketplaceRequests from "../../../../hooks/useMarketplaceRequests";
@@ -13,6 +13,7 @@ import { ReceivedRequestCard } from "./cards/ReceivedRequestCard";
1313
import { RequestCard } from "./cards/RequestCard";
1414
import { ViewRequestsFilters } from "./ViewRequestsFilters";
1515
import { ExchangeSidebarStatus } from "../../../../pages/Exchange";
16+
import { MoonLoader } from "react-spinners";
1617

1718
type Props = {
1819
setExchangeSidebarStatus: Dispatch<SetStateAction<ExchangeSidebarStatus>>
@@ -53,6 +54,34 @@ const RequestCardSkeletons = () => {
5354
</>
5455
}
5556

57+
const ViewMoreButton = ({
58+
hasNext,
59+
setSize,
60+
size,
61+
isValidating
62+
}: {
63+
hasNext: boolean
64+
setSize: Dispatch<SetStateAction<number>>
65+
size: number
66+
isValidating: boolean
67+
}) => {
68+
return <>
69+
{hasNext &&
70+
<Button
71+
variant="secondary"
72+
onClick={() => {
73+
setSize(size + 1)
74+
}}
75+
>
76+
{isValidating
77+
? <MoonLoader size={20} />
78+
: "Ver mais"
79+
}
80+
</Button>
81+
}
82+
</>
83+
}
84+
5685
export const ViewRequests = ({
5786
setExchangeSidebarStatus
5887
}: Props) => {
@@ -66,31 +95,10 @@ export const ViewRequests = ({
6695
// This is to keep track of the request of the request card that is currently open
6796
const [chosenRequest, setChosenRequest] = useState<MarketplaceRequest | null>(null);
6897

69-
const { data, size, setSize, isLoading } = useMarketplaceRequests(
98+
const { requests, size, setSize, isLoading, hasNext, isValidating } = useMarketplaceRequests(
7099
filterCourseUnitNames, requestTypeFilters[currentRequestTypeFilter], classesFilter
71100
);
72101

73-
const requests = data ? [].concat(...data) : [];
74-
75-
const onScroll = () => {
76-
if (!requestCardsContainerRef.current) return;
77-
78-
if ((requestCardsContainerRef.current.scrollHeight - requestCardsContainerRef.current.scrollTop)
79-
<= requestCardsContainerRef.current.clientHeight + 100
80-
) {
81-
setSize(size + 1);
82-
}
83-
}
84-
85-
useEffect(() => {
86-
if (!requestCardsContainerRef.current) return;
87-
88-
requestCardsContainerRef.current.addEventListener('scroll', onScroll);
89-
return () => {
90-
if (requestCardsContainerRef.current) requestCardsContainerRef.current.removeEventListener('scroll', onScroll);
91-
}
92-
}, []);
93-
94102
return <div className="relative flex flex-row flex-wrap items-center justify-center gap-x-2 gap-y-2 lg:justify-start">
95103
<div className="flex flex-row justify-between items-center w-full">
96104
<h1 className="font-bold text-xl">Pedidos</h1>
@@ -138,6 +146,12 @@ export const ViewRequests = ({
138146
<RequestCard />
139147
</CommonRequestCard>
140148
))}
149+
<ViewMoreButton
150+
hasNext={hasNext}
151+
setSize={setSize}
152+
size={size}
153+
isValidating={isValidating}
154+
/>
141155
</EmptyRequestGuard>
142156
}
143157
</>
@@ -170,6 +184,12 @@ export const ViewRequests = ({
170184
</CommonRequestCard>
171185

172186
))}
187+
<ViewMoreButton
188+
hasNext={hasNext}
189+
setSize={setSize}
190+
size={size}
191+
isValidating={isValidating}
192+
/>
173193
</EmptyRequestGuard>
174194
}
175195
</div>
@@ -198,6 +218,12 @@ export const ViewRequests = ({
198218
/>
199219
</CommonRequestCard>
200220
))}
221+
<ViewMoreButton
222+
hasNext={hasNext}
223+
setSize={setSize}
224+
size={size}
225+
isValidating={isValidating}
226+
/>
201227
</EmptyRequestGuard>
202228
}
203229
</div>

src/components/exchange/requests/view/cards/CommonCardHeader.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export const CommonCardHeader = ({
106106
<div className="flex flex-row gap-x-1 gap-y-2 flex-wrap">
107107
{request.options?.map((option) => {
108108
return (<RequestCardClassBadge
109-
key={option.course_info.acronym}
109+
key={option.course_info.acronym + `${crypto.randomUUID()}`}
110110
option={option}
111111
requestCardHovered={hovered}
112112
classUserGoesToName={option[classUserGoesToName].name}

src/components/exchange/requests/view/cards/RequestCard.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export const RequestCard = () => {
9696
<CardContent className={`p-0 px-4 ${open ? "" : "hidden"}`}>
9797
{request.options?.map((option) => (
9898
<ListRequestChanges
99-
key={"marketplace-request-card" + option.course_info.id}
99+
key={crypto.randomUUID()}
100100
option={option}
101101
selectedOptionsHook={[selectedOptions, setSelectedOptions]}
102102
setSelectAll={setSelectAll}

src/hooks/useMarketplaceRequests.tsx

+14-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import useSWRInfinite from "swr/infinite";
22
import { MarketplaceRequest } from "../@types";
33
import api from "../api/backend";
44
import exchangeRequestService from "../api/services/exchangeRequestService";
5+
import { useEffect, useState } from "react";
56

67
const getUrl = (requestType: string) => {
78
switch (requestType) {
@@ -22,6 +23,8 @@ const getUrl = (requestType: string) => {
2223
*
2324
*/
2425
export default (courseUnitNameFilter: Set<number>, requestType: string, classesFilter: Map<string, Set<string>>) => {
26+
const [hasNext, setHasNext] = useState<boolean>(true);
27+
2528
const classesFilterArray = Array.from(classesFilter, ([key, value]) => [key, Array.from(value)]);
2629
const classesFilterBase64 = btoa(JSON.stringify(classesFilterArray));
2730
const filters = `courseUnitNameFilter=${Array.from(courseUnitNameFilter).join(",")}&classesFilter=${classesFilterBase64}`;
@@ -37,8 +40,18 @@ export default (courseUnitNameFilter: Set<number>, requestType: string, classesF
3740
exchangeRequestService.retrieveMarketplaceRequest
3841
);
3942

43+
44+
const requests = data ? [].concat(...data.map((el) => el["data"])) : [];
45+
46+
useEffect(() => {
47+
if(data) {
48+
setHasNext(data[data.length - 1]["page"]["has_next"]);
49+
}
50+
}, [data])
51+
4052
return {
41-
data,
53+
requests,
54+
hasNext,
4255
isLoading,
4356
size,
4457
isValidating,

0 commit comments

Comments
 (0)