Skip to content

Commit

Permalink
chore: seperated PaginationCarousel into its own component
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbrusegard committed Jan 26, 2024
1 parent 586cc70 commit d9a0056
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 114 deletions.
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"allRightsReserved": "All rights reserved"
},
"news": {
"title": "News"
"title": "News",
"page": "Page"
}
}
3 changes: 2 additions & 1 deletion messages/no.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"allRightsReserved": "Alle rettigheter reservert"
},
"news": {
"title": "Nyheter"
"title": "Nyheter",
"page": "Side"
}
}
2 changes: 1 addition & 1 deletion src/app/[locale]/(dashboard)/news/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,14 @@ export default function News({
</div>
<Separator className='my-6' />
<NewsItemGrid
pageQueryName={locale === 'en' ? 'page' : 'side'}
newsData={mockData}
t={{
morePages: useTranslations('ui')('morePages'),
goToPreviousPage: useTranslations('ui')('goToPreviousPage'),
goToNextPage: useTranslations('ui')('goToNextPage'),
previous: useTranslations('ui')('previous'),
next: useTranslations('ui')('next'),
page: t('page'),
}}
/>
</>
Expand Down
9 changes: 6 additions & 3 deletions src/components/layout/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
'use client';

import { type ReactNode } from 'react';

import { cx } from '@/lib/utils';

type Props = {
type MainProps = {
children?: ReactNode;
mainClassName?: string;
className?: string;
};

function Main({ children, mainClassName, className }: Props) {
function Main({ children, mainClassName, className }: MainProps) {
return (
<main className={cx('flex w-full flex-grow justify-center', mainClassName)}>
<div
className={cx(
'h-full w-full max-w-screen-2xl px-4 sm:px-11 md:px-16 lg:px-24',
'h-full w-full max-w-screen-2xl px-4 duration-1000 animate-in fade-in max-md:slide-in-from-left-8 sm:px-11 md:px-16 md:slide-in-from-top-8 lg:px-24',
className,
)}
id='main'
>
{children}
</div>
Expand Down
129 changes: 129 additions & 0 deletions src/components/layout/PaginationCarousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { cx } from '@/lib/utils';

import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/Pagination';

type PaginationCarouselProps = {
className?: string;
page: number;
setPage: (page: number) => void;
totalPages: number;
t: {
goToPreviousPage: string;
previous: string;
morePages: string;
goToNextPage: string;
next: string;
};
};

function PaginationCarousel({
className,
page,
setPage,
totalPages,
t,
}: PaginationCarouselProps) {
async function handlePrevious(e: React.MouseEvent<HTMLAnchorElement>) {
e.preventDefault();
if (page > 1) {
setPage(page - 1);
}
}

async function handleNext(e: React.MouseEvent<HTMLAnchorElement>) {
e.preventDefault();
if (page < totalPages) {
setPage(page + 1);
}
}

async function handlePageClick(
e: React.MouseEvent<HTMLAnchorElement>,
pageNum: number,
) {
e.preventDefault();
setPage(pageNum);
}

let pagesToDisplay = [];
if (page === 1) {
pagesToDisplay = [1, 2, 3].filter((pageNum) => pageNum <= totalPages);
} else if (page === totalPages) {
pagesToDisplay = [totalPages - 2, totalPages - 1, totalPages].filter(
(pageNum) => pageNum >= 1,
);
} else {
pagesToDisplay = [page - 1, page, page + 1];
}

return (
<Pagination className={className}>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
className={cx(
page === 1 &&
'cursor-not-allowed opacity-50 hover:bg-transparent',
)}
href='#'
onClick={handlePrevious}
goToPreviousPage={t.goToPreviousPage}
previous={t.previous}
aria-disabled={page === 1}
tabIndex={page === 1 ? -1 : 0}
/>
</PaginationItem>
{pagesToDisplay[0] !== undefined && pagesToDisplay[0] > 1 && (
<PaginationItem>
<PaginationEllipsis morePages={t.morePages} />
</PaginationItem>
)}
{pagesToDisplay.map(
(pageNum) =>
pageNum > 0 &&
pageNum <= totalPages && (
<PaginationItem key={pageNum}>
<PaginationLink
href='#'
onClick={(e) => handlePageClick(e, pageNum)}
isActive={pageNum === page}
>
{pageNum}
</PaginationLink>
</PaginationItem>
),
)}
{pagesToDisplay[pagesToDisplay.length - 1] !== undefined &&
pagesToDisplay[pagesToDisplay.length - 1]! < totalPages && (
<PaginationItem>
<PaginationEllipsis morePages={t.morePages} />
</PaginationItem>
)}
<PaginationItem>
<PaginationNext
className={cx(
page === totalPages &&
'cursor-not-allowed opacity-50 hover:bg-transparent',
)}
href='#'
onClick={handleNext}
goToNextPage={t.goToNextPage}
next={t.next}
aria-disabled={page === totalPages}
tabIndex={page === totalPages ? -1 : 0}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
);
}

export { PaginationCarousel };
119 changes: 11 additions & 108 deletions src/components/news/NewsItemGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,10 @@

import { parseAsInteger, useQueryState } from 'nuqs';

import { cx } from '@/lib/utils';

import { PaginationCarousel } from '@/components/layout/PaginationCarousel';
import { NewsItem } from '@/components/news/NewsItem';
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/Pagination';

type NewsItemGridProps = {
pageQueryName: string;
newsData: {
id: number;
title: string;
Expand All @@ -29,16 +18,14 @@ type NewsItemGridProps = {
goToNextPage: string;
previous: string;
next: string;
page: string;
};
};

function NewsItemGrid({ pageQueryName, newsData, t }: NewsItemGridProps) {
function NewsItemGrid({ newsData, t }: NewsItemGridProps) {
const itemsDisplayedAsCards = 4;
const itemsPerPage = 6;
const [page, setPage] = useQueryState(
pageQueryName,
parseAsInteger.withDefault(1),
);
const [page, setPage] = useQueryState(t.page, parseAsInteger.withDefault(1));

const start = (page - 1) * itemsPerPage + itemsDisplayedAsCards;
const end = start + itemsPerPage;
Expand All @@ -48,39 +35,6 @@ function NewsItemGrid({ pageQueryName, newsData, t }: NewsItemGridProps) {
(newsData.length - itemsDisplayedAsCards) / itemsPerPage,
);

async function handlePrevious(e: React.MouseEvent<HTMLAnchorElement>) {
e.preventDefault();
if (page > 1) {
await setPage(page - 1);
}
}

async function handleNext(e: React.MouseEvent<HTMLAnchorElement>) {
e.preventDefault();
if (page < totalPages) {
await setPage(page + 1);
}
}

async function handlePageClick(
e: React.MouseEvent<HTMLAnchorElement>,
pageNum: number,
) {
e.preventDefault();
await setPage(pageNum);
}

let pagesToDisplay = [];
if (page === 1) {
pagesToDisplay = [1, 2, 3].filter((pageNum) => pageNum <= totalPages);
} else if (page === totalPages) {
pagesToDisplay = [totalPages - 2, totalPages - 1, totalPages].filter(
(pageNum) => pageNum >= 1,
);
} else {
pagesToDisplay = [page - 1, page, page + 1];
}

return (
<>
<div className='grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3'>
Expand All @@ -94,64 +48,13 @@ function NewsItemGrid({ pageQueryName, newsData, t }: NewsItemGridProps) {
/>
))}
</div>
<Pagination className='my-6'>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
className={cx(
page === 1 &&
'cursor-not-allowed opacity-50 hover:bg-transparent',
)}
href='#'
onClick={handlePrevious}
goToPreviousPage={t.goToPreviousPage}
previous={t.previous}
aria-disabled={page === 1}
tabIndex={page === 1 ? -1 : 0}
/>
</PaginationItem>
{pagesToDisplay[0] !== undefined && pagesToDisplay[0] > 1 && (
<PaginationItem>
<PaginationEllipsis morePages={t.morePages} />
</PaginationItem>
)}
{pagesToDisplay.map(
(pageNum) =>
pageNum > 0 &&
pageNum <= totalPages && (
<PaginationItem key={pageNum}>
<PaginationLink
href='#'
onClick={(e) => handlePageClick(e, pageNum)}
isActive={pageNum === page}
>
{pageNum}
</PaginationLink>
</PaginationItem>
),
)}
{pagesToDisplay[pagesToDisplay.length - 1] !== undefined &&
pagesToDisplay[pagesToDisplay.length - 1]! < totalPages && (
<PaginationItem>
<PaginationEllipsis morePages={t.morePages} />
</PaginationItem>
)}
<PaginationItem>
<PaginationNext
className={cx(
page === totalPages &&
'cursor-not-allowed opacity-50 hover:bg-transparent',
)}
href='#'
onClick={handleNext}
goToNextPage={t.goToNextPage}
next={t.next}
aria-disabled={page === totalPages}
tabIndex={page === totalPages ? -1 : 0}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
<PaginationCarousel
className='my-6'
page={page}
setPage={setPage}
totalPages={totalPages}
t={t}
/>
</>
);
}
Expand Down

0 comments on commit d9a0056

Please sign in to comment.