From 728368d712e280ce1d45204df411f42210f5d46a Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:59:24 +0100 Subject: [PATCH] Fix pagination bugs and refactor/abstract styling logic (#205) * Simplify TS * Abstract away pagination logic * Clean up * Fix bugs and refactor styling logic * Add comments * Fix border bug for single page * Fix search pagination --- .../15-final/app/dashboard/customers/page.tsx | 10 +- .../15-final/app/dashboard/invoices/page.tsx | 12 +- dashboard/15-final/app/lib/utils.ts | 33 ++++ .../15-final/app/ui/invoices/pagination.tsx | 171 ++++++++++-------- dashboard/15-final/app/ui/search.tsx | 2 + 5 files changed, 140 insertions(+), 88 deletions(-) diff --git a/dashboard/15-final/app/dashboard/customers/page.tsx b/dashboard/15-final/app/dashboard/customers/page.tsx index c45ee90..dcd62af 100644 --- a/dashboard/15-final/app/dashboard/customers/page.tsx +++ b/dashboard/15-final/app/dashboard/customers/page.tsx @@ -4,12 +4,10 @@ import CustomersTable from '@/app/ui/customers/table'; export default async function Page({ searchParams, }: { - searchParams: - | { - query: string | undefined; - page: string | undefined; - } - | undefined; + searchParams?: { + query?: string; + page?: string; + }; }) { const query = searchParams?.query || ''; diff --git a/dashboard/15-final/app/dashboard/invoices/page.tsx b/dashboard/15-final/app/dashboard/invoices/page.tsx index 11bfce8..fcf178a 100644 --- a/dashboard/15-final/app/dashboard/invoices/page.tsx +++ b/dashboard/15-final/app/dashboard/invoices/page.tsx @@ -8,15 +8,13 @@ import { lusitana } from '@/app/ui/fonts'; export default async function Page({ searchParams, }: { - searchParams: - | { - query: string | undefined; - page: string | undefined; - } - | undefined; + searchParams?: { + query?: string; + page?: string; + }; }) { const query = searchParams?.query || ''; - const currentPage = query ? 1 : Number(searchParams?.page || '1'); + const currentPage = Number(searchParams?.page || '1'); const { invoices, totalPages } = await fetchFilteredInvoices( query, diff --git a/dashboard/15-final/app/lib/utils.ts b/dashboard/15-final/app/lib/utils.ts index 4dce958..b7f7cff 100644 --- a/dashboard/15-final/app/lib/utils.ts +++ b/dashboard/15-final/app/lib/utils.ts @@ -34,3 +34,36 @@ export const generateYAxis = (revenue: Revenue[]) => { return { yAxisLabels, topLabel }; }; + +export const generatePagination = (currentPage: number, totalPages: number) => { + // If the total number of pages is 7 or less, + // display all pages without any ellipsis. + if (totalPages <= 7) { + return Array.from({ length: totalPages }, (_, i) => i + 1); + } + + // If the current page is among the first 3 pages, + // show the first 3, an ellipsis, and the last 2 pages. + if (currentPage <= 3) { + return [1, 2, 3, '...', totalPages - 1, totalPages]; + } + + // If the current page is among the last 3 pages, + // show the first 2, an ellipsis, and the last 3 pages. + if (currentPage >= totalPages - 2) { + return [1, 2, '...', totalPages - 2, totalPages - 1, totalPages]; + } + + // If the current page is somewhere in the middle, + // show the first page, an ellipsis, the current page and its neighbors, + // another ellipsis, and the last page. + return [ + 1, + '...', + currentPage - 1, + currentPage, + currentPage + 1, + '...', + totalPages, + ]; +}; diff --git a/dashboard/15-final/app/ui/invoices/pagination.tsx b/dashboard/15-final/app/ui/invoices/pagination.tsx index 5af0925..a9c6dba 100644 --- a/dashboard/15-final/app/ui/invoices/pagination.tsx +++ b/dashboard/15-final/app/ui/invoices/pagination.tsx @@ -1,9 +1,10 @@ 'use client'; import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/24/outline'; -import { usePathname, useSearchParams } from 'next/navigation'; import clsx from 'clsx'; import Link from 'next/link'; +import { generatePagination } from '@/app/lib/utils'; +import { usePathname, useSearchParams } from 'next/navigation'; export default function Pagination({ currentPage, @@ -15,94 +16,114 @@ export default function Pagination({ const pathname = usePathname(); const searchParams = useSearchParams(); - const allPages = Array.from({ length: totalPages }, (_, i) => i + 1); - const PreviousPageTag = Link; - const NextPageTag = Link; - - const createPageUrl = (pageNumber: number | string) => { + const createPageURL = (pageNumber: number | string) => { const params = new URLSearchParams(searchParams); params.set('page', pageNumber.toString()); return `${pathname}?${params.toString()}`; }; - let pagesToShow = []; - - if (totalPages <= 7) { - pagesToShow = allPages; - } else if (currentPage <= 3) { - pagesToShow = [1, 2, 3, '...', totalPages - 1, totalPages]; - } else if (currentPage >= totalPages - 2) { - pagesToShow = [1, 2, '...', totalPages - 2, totalPages - 1, totalPages]; - } else { - pagesToShow = [ - 1, - '...', - currentPage - 1, - currentPage, - currentPage + 1, - '...', - totalPages, - ]; - } + const allPages = generatePagination(currentPage, totalPages); return (