Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add pagination #103

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions apps/web/components/molecules/pagginationArrow/paginationArrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { VisuallyHidden } from 'ui';
import {
ChevronLeftIcon as PrevPageIcon,
ChevronRightIcon as NextPageIcon,
} from '@heroicons/react/20/solid';
import clsx from 'clsx';

type PaginationArrowProps = {
pageNumber: number;
isDisabled: boolean;
type: 'next' | 'prev';
};

export const PaginationArrow = ({
pageNumber,
isDisabled,
type,
}: PaginationArrowProps) => {
return (
<a
href={isDisabled ? '' : `?page=${pageNumber}`}
className={clsx(
type === 'prev' && 'rounded-l-lg',
type === 'next' && 'rounded-r-lg',
'relative inline-flex items-center px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0',
)}
>
{type === 'prev' && (
<>
<VisuallyHidden>Poprzednia strona</VisuallyHidden>
<PrevPageIcon className="h-5 w-5" aria-hidden="true" />
</>
)}
{type === 'next' && (
<>
<VisuallyHidden>Następna strona</VisuallyHidden>
<NextPageIcon className="h-5 w-5" aria-hidden="true" />
</>
)}
</a>
);
};
24 changes: 24 additions & 0 deletions apps/web/components/molecules/paginationItem/paginationItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import clsx from 'clsx';

type PaginationItemProps = {
pageNumber: number;
isCurrent: boolean;
};

export const PaginationItem = ({
pageNumber,
isCurrent,
}: PaginationItemProps) => {
return (
<a
href={`?page=${pageNumber}`}
className={clsx(
isCurrent
? 'relative z-10 inline-flex items-center bg-blue-600 px-4 py-2 text-sm font-semibold text-white focus:z-20 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600'
: 'relative hidden items-center px-4 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 md:inline-flex',
)}
>
{pageNumber}
</a>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChallengeItem } from 'molecules/challengeItem/challengeItem';
import type { Challenge } from '../../../types/types';
import { Pagination } from 'organisms/pagination/pagination';

type TasksListProps = {
challenges: Challenge[];
Expand All @@ -13,9 +14,8 @@ export const ChallengesList = ({ challenges }: TasksListProps) => {
})}
</ul>

{/*<div className="h-96 rounded-lg border-4 border-dashed border-gray-200 lg:h-full">*/}
{/* Zadania*/}
{/*</div>*/}
{/*<Pagination numberOfPages={challenges.length} />*/}
<Pagination numberOfItems={5} />
</div>
);
};
92 changes: 92 additions & 0 deletions apps/web/components/organisms/pagination/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useRouter } from 'next/router';
import { PaginationItem } from 'molecules/paginationItem/paginationItem';
import { PaginationArrow } from 'molecules/pagginationArrow/paginationArrow';

type PaginationProps = {
numberOfItems: number;
};

export const Pagination = ({ numberOfItems }: PaginationProps) => {
const router = useRouter();
const currentPage: number =
router.query.page && !isNaN(Number(router.query.page))
? Number(router.query.page)
: 1;
const perPage =
router.query.page && !isNaN(Number(router.query.limit))
? Number(router.query.limit)
: 11;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this number "11" ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be moved to constant SOMETHING_NUMBER

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this number "11" ?

It's default quantity of items per page

const totalPages = Math.ceil(numberOfItems / perPage);

const prevPageNumber = currentPage - 1;
const nextPageNumber = currentPage + 1;
const startNumberOfItemsOnCurrentPage = (currentPage - 1) * perPage + 1;
const endNumberOfItemsOnCurrentPage =
currentPage !== totalPages ? currentPage * perPage : numberOfItems;

return (
<div className="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
<div className="flex flex-1 justify-between sm:hidden">
<a
href={`?page=${prevPageNumber}`}
className="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
>
Poprzednia
</a>
<a
href={`?page=${nextPageNumber}`}
className="relative z-10 inline-flex items-center bg-blue-600 px-4 py-2 text-sm font-semibold text-white focus:z-20 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
{currentPage}
</a>
<a
href="apps/web/components/organisms/pagination#"
className="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
>
Następna
</a>
</div>
<div className="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
<div>
<p className="text-sm text-gray-700">
<span className="font-medium">
{startNumberOfItemsOnCurrentPage}
</span>
-
<span className="font-medium">{endNumberOfItemsOnCurrentPage}</span>{' '}
z <span className="font-medium">{numberOfItems}</span> wyników
</p>
</div>
<div>
<nav
className="isolate inline-flex -space-x-px rounded-md shadow-sm"
aria-label="Pagination"
>
<PaginationArrow
pageNumber={prevPageNumber}
isDisabled={currentPage === 1}
type="prev"
/>
{Array.from({ length: totalPages }, (_, i) => (
<PaginationItem
key={i}
pageNumber={i + 1}
isCurrent={i + 1 === currentPage}
/>
))}
{totalPages > 5 && (
<span className="relative inline-flex items-center px-4 py-2 text-sm font-semibold text-gray-700 ring-1 ring-inset ring-gray-300 focus:outline-offset-0">
...
</span>
)}
<PaginationArrow
pageNumber={nextPageNumber}
isDisabled={currentPage === totalPages}
type="next"
/>
</nav>
</div>
</div>
</div>
);
};