diff --git a/README.md b/README.md index be8a8c6b6..dee056e91 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,29 @@ > Here is the [working version](https://mate-academy.github.io/react_pagination/) -You a given a list of items and markup for the `Pagination`. Implement the +You a given a list of items and markup for the `Pagination`. Implement the `Pagination` as a stateless component to show only the items for a current page. 1. The `Pagination` should be used with the next props: - ```jsx harmony - { ... }} - /> - ``` + ```jsx harmony + { ... }} + /> + ``` 1. Keep the HTML stucture `data-cy` attributes; 1. Show all the existing pages considering `total` and `perPage` 1. Current page should be highlighted with `li.active`; 1. `onPageChange` callback should be triggered only if page was changed; 1. The `App` should listen to the `onPageChange` and save a new page; 1. `«` and `»` links should open the prev and the next pages accordingly - - disable each of them if it is already the first or the last page (use `li.disabled` and `a[aria-disabled="true"]`) + - disable each of them if it is already the first or the last page (use `li.disabled` and `a[aria-disabled="true"]`) 1. Show the pagination info inside `data-cy="info"` in the next format `Page 1 (items 1 - 5 of 42)`; 1. Implement the ` - - - - - - + const handlePageChange = (page: number) => { + setSearchParams({ page: String(page), perPage: String(perPage) }); + }; - - + const handlePerPageChange = (value: number) => { + setSearchParams({ page: '1', perPage: String(value) }); + }; + + // ITEMS + const items = Array.from({ length: TOTAL }, (_, i) => `Item ${i + 1}`); + + const start = (currentPage - 1) * perPage; + const end = start + perPage; + const visibleItems = items.slice(start, end); + + return ( +
+ - {/* Move this markup to Pagination */} -
    -
  • Item 1
  • -
  • Item 2
  • -
  • Item 3
  • -
  • Item 4
  • -
  • Item 5
  • + {visibleItems.map(item => ( +
  • + {item} +
  • + ))}
+ +
); }; - -export default App; diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx index e417a09fc..43959ed5c 100644 --- a/src/components/Pagination/Pagination.tsx +++ b/src/components/Pagination/Pagination.tsx @@ -1 +1,90 @@ -export const Pagination = () => {}; +import React from 'react'; + +type Props = { + total: number; + perPage: number; + currentPage?: number; // optional + onPageChange: (page: number) => void; +}; + +export const Pagination: React.FC = ({ + total, + perPage, + currentPage = 1, // default value + onPageChange, +}) => { + const totalPages = Math.ceil(total / perPage); + const pages = Array.from({ length: totalPages }, (_, i) => i + 1); + + const goTo = (page: number) => { + if (page >= 1 && page <= totalPages && page !== currentPage) { + onPageChange(page); + } + }; + + const firstItem = (currentPage - 1) * perPage + 1; + const lastItem = Math.min(currentPage * perPage, total); + + return ( + <> +

+ Page {currentPage} (items {firstItem} - {lastItem} of {total}) +

+ + + + ); +}; diff --git a/src/index.tsx b/src/index.tsx index 226f3f4bd..202bc516f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,10 @@ import { createRoot } from 'react-dom/client'; +import { BrowserRouter } from 'react-router-dom'; import { App } from './App'; -createRoot(document.getElementById('root') as HTMLElement).render(); +createRoot(document.getElementById('root') as HTMLElement).render( + + + , +); diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index ab24e2b56..000000000 --- a/src/utils.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function getNumbers(from: number, to: number): number[] { - const numbers = []; - - for (let n = from; n <= to; n += 1) { - numbers.push(n); - } - - return numbers; -}