diff --git a/apps/web/src/containers/private/browse.tsx b/apps/web/src/containers/private/browse.tsx index 0ac72f75..2f9505bb 100644 --- a/apps/web/src/containers/private/browse.tsx +++ b/apps/web/src/containers/private/browse.tsx @@ -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; @@ -19,12 +21,70 @@ const sortOptions: SelectOption[] = [ ]; const Browse = ({ data }: Props) => { + const [snippetList, setSnippetList] = useState(data.items); const [sortOption, setSortOption] = useState(sortOptions[0]); const [search, setSearch] = useState(); + 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 ( @@ -40,6 +100,7 @@ const Browse = ({ data }: Props) => { name="account-number" placeholder="Search..." type="text" + onChange={(e) => onSearchChange(e.target.value)} />
@@ -49,21 +110,31 @@ const Browse = ({ data }: Props) => { className="w-1/5 cursor-pointer" options={sortOptions} value={sortOption} - onChange={setSortOption} + onChange={onSortOptionChange} />
- {snippets.map((snippet) => ( + {snippetList.map((snippet) => ( ))}
- - diff --git a/apps/web/src/hooks/usePaginationToken.ts b/apps/web/src/hooks/usePaginationToken.ts new file mode 100644 index 00000000..7c55a519 --- /dev/null +++ b/apps/web/src/hooks/usePaginationToken.ts @@ -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([{ 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, + }; +}; diff --git a/packages/front/services/snippets/public-snippets.ts b/packages/front/services/snippets/public-snippets.ts index 08edb5c8..f702f14b 100644 --- a/packages/front/services/snippets/public-snippets.ts +++ b/packages/front/services/snippets/public-snippets.ts @@ -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 => { @@ -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, @@ -53,6 +55,8 @@ export const usePublicSnippets = () => { }; return { + data: formatPublicSnippetsResult(data), findPublicSnippets, + isLoading: loading, }; };