@@ -15,7 +15,7 @@ import { Link } from "react-router";
|
|||||||
import { Helmet } from "react-helmet-async";
|
import { Helmet } from "react-helmet-async";
|
||||||
import type { PeopleListPageQuery as PeopleListPageQueryType } from "./__generated__/PeopleListPageQuery.graphql";
|
import type { PeopleListPageQuery as PeopleListPageQueryType } from "./__generated__/PeopleListPageQuery.graphql";
|
||||||
|
|
||||||
const ITEMS_PER_PAGE = 20;
|
const ITEMS_PER_PAGE = 25;
|
||||||
|
|
||||||
const PeopleListPageQuery = graphql`
|
const PeopleListPageQuery = graphql`
|
||||||
query PeopleListPageQuery(
|
query PeopleListPageQuery(
|
||||||
@@ -59,10 +59,61 @@ const deletePeopleMutation = graphql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
function LoadAboveButton({
|
||||||
|
pageInfo,
|
||||||
|
isPending,
|
||||||
|
onPageChange,
|
||||||
|
}: {
|
||||||
|
pageInfo: {
|
||||||
|
hasNextPage: boolean;
|
||||||
|
hasPreviousPage: boolean;
|
||||||
|
} | null | undefined;
|
||||||
|
isPending: boolean;
|
||||||
|
onPageChange: (direction: "prev") => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => onPageChange("prev")}
|
||||||
|
disabled={isPending || !pageInfo?.hasPreviousPage}
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
{isPending ? "Loading..." : "Load above"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function LoadBelowButton({
|
||||||
|
pageInfo,
|
||||||
|
isPending,
|
||||||
|
onPageChange,
|
||||||
|
}: {
|
||||||
|
pageInfo: {
|
||||||
|
hasNextPage: boolean;
|
||||||
|
hasPreviousPage: boolean;
|
||||||
|
} | null | undefined;
|
||||||
|
isPending: boolean;
|
||||||
|
onPageChange: (direction: "next") => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => onPageChange("next")}
|
||||||
|
disabled={isPending || !pageInfo?.hasNextPage}
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
{isPending ? "Loading..." : "Load below"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function PeopleListPageContent({
|
function PeopleListPageContent({
|
||||||
queryRef,
|
queryRef,
|
||||||
onPageChange,
|
onPageChange,
|
||||||
loadQuery,
|
|
||||||
}: {
|
}: {
|
||||||
queryRef: PreloadedQuery<PeopleListPageQueryType>;
|
queryRef: PreloadedQuery<PeopleListPageQueryType>;
|
||||||
onPageChange: (params: {
|
onPageChange: (params: {
|
||||||
@@ -71,27 +122,38 @@ function PeopleListPageContent({
|
|||||||
last?: number;
|
last?: number;
|
||||||
before?: string;
|
before?: string;
|
||||||
}) => void;
|
}) => void;
|
||||||
loadQuery: LoadQueryType;
|
|
||||||
}) {
|
}) {
|
||||||
const data = usePreloadedQuery(PeopleListPageQuery, queryRef);
|
const data = usePreloadedQuery(PeopleListPageQuery, queryRef);
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const peoples = data.node.peoples?.edges.map((edge) => edge?.node) ?? [];
|
const peoples = data.node.peoples?.edges.map((edge) => edge?.node) ?? [];
|
||||||
const pageInfo = data.node.peoples?.pageInfo;
|
const pageInfo = data.node.peoples?.pageInfo;
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
const [deletePeople] = useMutation(deletePeopleMutation);
|
const [deletePeople] = useMutation(deletePeopleMutation);
|
||||||
|
|
||||||
const handlePageChange = (direction: "prev" | "next") => {
|
const handlePageChange = (direction: "prev" | "next") => {
|
||||||
|
if (!pageInfo) return;
|
||||||
|
|
||||||
|
if (direction === "next" && !pageInfo.hasNextPage) return;
|
||||||
|
if (direction === "prev" && !pageInfo.hasPreviousPage) return;
|
||||||
|
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
if (direction === "prev") {
|
const params =
|
||||||
onPageChange({
|
direction === "next"
|
||||||
last: ITEMS_PER_PAGE,
|
? { first: ITEMS_PER_PAGE, after: pageInfo.endCursor }
|
||||||
before: pageInfo?.startCursor,
|
: { last: ITEMS_PER_PAGE, before: pageInfo.startCursor };
|
||||||
});
|
|
||||||
} else {
|
setSearchParams((prev) => {
|
||||||
onPageChange({
|
if (direction === "next") {
|
||||||
first: ITEMS_PER_PAGE,
|
prev.set("after", pageInfo.endCursor!);
|
||||||
after: pageInfo?.endCursor,
|
prev.delete("before");
|
||||||
});
|
} else {
|
||||||
}
|
prev.set("before", pageInfo.startCursor!);
|
||||||
|
prev.delete("after");
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
});
|
||||||
|
|
||||||
|
onPageChange(params);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,6 +172,13 @@ function PeopleListPageContent({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<LoadAboveButton
|
||||||
|
pageInfo={pageInfo}
|
||||||
|
isPending={isPending}
|
||||||
|
onPageChange={() => handlePageChange("prev")}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{peoples.map((person) => (
|
{peoples.map((person) => (
|
||||||
<Link
|
<Link
|
||||||
@@ -164,15 +233,12 @@ function PeopleListPageContent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted() {
|
onCompleted() {
|
||||||
loadQuery(
|
onPageChange({
|
||||||
{
|
first: ITEMS_PER_PAGE,
|
||||||
first: ITEMS_PER_PAGE,
|
after: undefined,
|
||||||
after: undefined,
|
last: undefined,
|
||||||
last: undefined,
|
before: undefined,
|
||||||
before: undefined,
|
});
|
||||||
},
|
|
||||||
{ fetchPolicy: "network-only" },
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -184,22 +250,11 @@ function PeopleListPageContent({
|
|||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<div className="flex gap-2 justify-end mt-4">
|
<LoadBelowButton
|
||||||
<Button
|
pageInfo={pageInfo}
|
||||||
variant="outline"
|
isPending={isPending}
|
||||||
onClick={() => handlePageChange("prev")}
|
onPageChange={() => handlePageChange("next")}
|
||||||
disabled={isPending || !pageInfo?.hasPreviousPage}
|
/>
|
||||||
>
|
|
||||||
{isPending ? "Loading..." : "Previous"}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => handlePageChange("next")}
|
|
||||||
disabled={isPending || !pageInfo?.hasNextPage}
|
|
||||||
>
|
|
||||||
{isPending ? "Loading..." : "Next"}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -300,7 +355,6 @@ export default function PeopleListPage() {
|
|||||||
<PeopleListPageContent
|
<PeopleListPageContent
|
||||||
queryRef={queryRef}
|
queryRef={queryRef}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
loadQuery={loadQuery}
|
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<048f9d727dd07032be161da7019c6ebe>>
|
* @generated SignedSource<<98591652ea931191ef7210e363e0adad>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -88,6 +88,7 @@ return {
|
|||||||
},
|
},
|
||||||
"name": "VendorListPage_vendors",
|
"name": "VendorListPage_vendors",
|
||||||
"selections": [
|
"selections": [
|
||||||
|
(v1/*: any*/),
|
||||||
{
|
{
|
||||||
"alias": "vendors",
|
"alias": "vendors",
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -195,14 +196,13 @@ return {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
}
|
||||||
(v1/*: any*/)
|
|
||||||
],
|
],
|
||||||
"type": "Organization",
|
"type": "Organization",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "753e6b32cc21645852de27cf6f23c769";
|
(node as any).hash = "f61c6a2996a9fe95b71d9c0c2fe0530c";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
Reference in New Issue
Block a user