Skip to content

Commit

Permalink
feat(snippet): implement pagination navigation on client side - wip
Browse files Browse the repository at this point in the history
  • Loading branch information
tericcabrel committed Nov 1, 2023
1 parent 815f18d commit 2f79443
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 12 deletions.
85 changes: 78 additions & 7 deletions apps/web/src/containers/private/browse.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Button } from '@sharingan/front/forms/button';
import { SelectInput } from '@sharingan/front/forms/select-input';
import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon, SearchIcon } from '@sharingan/front/icons';
import { usePublicSnippets } from '@sharingan/front/services';
import { SelectOption } from '@sharingan/front/typings/components';
import { PublicSnippetResult } from '@sharingan/front/typings/queries';
import { PublicSnippetItem, PublicSnippetResult } from '@sharingan/front/typings/queries';
import { NextSeo } from 'next-seo';
import { useState } from 'react';

import { Layout } from '@/components/layout/private/layout';
import { PublicSnippet } from '@/components/snippets/public-snippet';
import { usePaginationToken } from '@/hooks/usePaginationToken';

type Props = {
data: PublicSnippetResult;
Expand All @@ -19,12 +21,70 @@ const sortOptions: SelectOption[] = [
];

const Browse = ({ data }: Props) => {
const [snippetList, setSnippetList] = useState<PublicSnippetItem[]>(data.items);
const [sortOption, setSortOption] = useState<SelectOption>(sortOptions[0]);
const [search, setSearch] = useState<string | undefined>();
const { addPageFromNext, addPageFromPrevious, canGoBack, canGoForward, getPage } = usePaginationToken(
data.nextToken ?? null,
);

const { findPublicSnippets, isLoading } = usePublicSnippets();

const onSearchChange = (value: string) => {
setSearch(value);

console.log('Search => ', search);

// TODO make request
};

const onSortOptionChange = (option: SelectOption) => {
setSortOption(option);

console.log('Sort option => ', sortOption);

// TODO make request
};

const onNextItemClick = async () => {
const page = getPage();

await findPublicSnippets({
itemPerPage: data.itemPerPage,
nextToken: page?.nextToken,
// keyword: search,
// sort: sortOption.id,
onCompleted: (data) => {
console.log('Result Next => ', data);

if (!data) {
return;
}
setSnippetList(data.items);
addPageFromNext(data.nextToken ?? null);
},
});
};

const onPreviousItemClick = async () => {
const page = getPage();

console.log(data);
await findPublicSnippets({
itemPerPage: data.itemPerPage,
nextToken: page?.previousToken,
// keyword: search,
// sort: sortOption.id,
onCompleted: (data) => {
console.log('Result Previous => ', data);

const snippets = data.items;
if (!data) {
return;
}
setSnippetList(data.items);
addPageFromPrevious(data.nextToken ?? null);
},
});
};

return (
<Layout>
Expand All @@ -40,6 +100,7 @@ const Browse = ({ data }: Props) => {
name="account-number"
placeholder="Search..."
type="text"
onChange={(e) => onSearchChange(e.target.value)}
/>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
<SearchIcon className="h-5 w-5 text-gray-400" />
Expand All @@ -49,21 +110,31 @@ const Browse = ({ data }: Props) => {
className="w-1/5 cursor-pointer"
options={sortOptions}
value={sortOption}
onChange={setSortOption}
onChange={onSortOptionChange}
/>
</div>
<div className="px-4 py-8 sm:px-0">
<div className="space-y-6 min-h-96">
{snippets.map((snippet) => (
{snippetList.map((snippet) => (
<PublicSnippet key={snippet.id} snippet={snippet} />
))}
</div>
<div className="w-full flex justify-center mt-10 space-x-4">
<Button className="bg-gray-200 w-auto items-center" color="white-gray">
<Button
className="bg-gray-200 w-auto items-center"
color="white-gray"
disabled={!canGoBack}
onClick={onPreviousItemClick}
>
<ChevronDoubleLeftIcon className="w-6 h-4" />
Previous
</Button>
<Button className="bg-gray-200 w-auto items-center" color="white-gray">
<Button
className="bg-gray-200 w-auto items-center"
color="white-gray"
disabled={!canGoForward}
onClick={onNextItemClick}
>
Next
<ChevronDoubleRightIcon className="w-6 h-4" />
</Button>
Expand Down
46 changes: 46 additions & 0 deletions apps/web/src/hooks/usePaginationToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useState } from 'react';

type Page = {
nextToken: string | null;
previousToken: string | null;
};

export const usePaginationToken = (nextToken: string | null) => {
const [pages, setPages] = useState<Page[]>([{ nextToken, previousToken: null }]);
const [canGoForward, setCanGoForward] = useState(!!nextToken);
const [canGoBack, setCanGoBack] = useState(false);

const getPage = (): Page | undefined => {
return pages.pop();
};

const addPageFromNext = (token: string | null) => {
const lastPage = pages.length > 0 ? pages[pages.length - 1] : undefined;

const newPage: Page = {
nextToken: token,
previousToken: lastPage?.nextToken ?? null,
};

setPages([...pages, newPage]);

setCanGoBack(!!newPage.previousToken);
setCanGoForward(!!newPage.nextToken);
};

const addPageFromPrevious = (token: string | null) => {
// should do nothing ???
const lastPage = pages.length > 0 ? pages[pages.length - 1] : undefined;

setCanGoBack(!!lastPage?.previousToken);
setCanGoForward(!!lastPage?.nextToken);
};

return {
addPageFromNext,
addPageFromPrevious,
canGoBack,
canGoForward,
getPage,
};
};
14 changes: 9 additions & 5 deletions packages/front/services/snippets/public-snippets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { PublicSnippetsQuery } from '../../graphql/generated';
import { useLazyPublicSnippetsQuery } from '../../graphql/snippets/queries/public-snippets';
import { PublicSnippetResult } from '../../typings/queries';

type UsePublicSnippetsArgs = {
type FindPublicSnippetsArgs = {
itemPerPage?: number | null;
nextToken?: string | null;
onCompleted: (result?: PublicSnippetResult) => void;
};

export const formatPublicSnippetsResult = (data?: PublicSnippetsQuery): PublicSnippetResult | undefined => {
Expand Down Expand Up @@ -37,12 +38,13 @@ export const formatPublicSnippetsResult = (data?: PublicSnippetsQuery): PublicSn
};

export const usePublicSnippets = () => {
const [query] = useLazyPublicSnippetsQuery();
const [query, { data, loading }] = useLazyPublicSnippetsQuery();

// const data = formatPublicSnippetsResult(query.data);

const findPublicSnippets = (args: UsePublicSnippetsArgs) => {
const findPublicSnippets = (args: FindPublicSnippetsArgs) => {
return query({
onCompleted: (data) => {
args.onCompleted(formatPublicSnippetsResult(data));
},
variables: {
args: {
itemPerPage: args.itemPerPage,
Expand All @@ -53,6 +55,8 @@ export const usePublicSnippets = () => {
};

return {
data: formatPublicSnippetsResult(data),
findPublicSnippets,
isLoading: loading,
};
};

0 comments on commit 2f79443

Please sign in to comment.