-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Develop #1420
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
base: master
Are you sure you want to change the base?
Develop #1420
Changes from all commits
c75a245
ee8f511
ae24801
9f7e074
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,36 @@ | ||
| import React from 'react'; | ||
| import './App.css'; | ||
| import { getNumbers } from './utils'; | ||
| import { Pagination } from './components/Pagination'; | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| const items = getNumbers(1, 42).map(n => `Item ${n}`); | ||
|
|
||
| export const App: React.FC = () => { | ||
| const [currentPage, setCurrentPage] = React.useState(1); | ||
| const [perPage, setPerPage] = React.useState(5); | ||
|
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The task requires synchronizing the
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the task requirements, the |
||
|
|
||
| return ( | ||
| <div className="container"> | ||
| <h1>Items with Pagination</h1> | ||
|
|
||
| <p className="lead" data-cy="info"> | ||
| Page 1 (items 1 - 5 of 42) | ||
| Page {currentPage} (items {(currentPage - 1) * perPage + 1} -{' '} | ||
| {Math.min(currentPage * perPage, items.length)} of {items.length}) | ||
| </p> | ||
|
|
||
| <div className="form-group row"> | ||
| <div className="col-3 col-sm-2 col-xl-1"> | ||
| <select | ||
| data-cy="perPageSelector" | ||
| id="perPageSelector" | ||
| className="form-control"> | ||
| className="form-control" | ||
| value={perPage} | ||
| onChange={e => { | ||
| setPerPage(Number(e.target.value)); | ||
| setCurrentPage(1); | ||
| }} | ||
| > | ||
| <option value="3">3</option> | ||
| <option value="5">5</option> | ||
| <option value="10">10</option> | ||
|
|
@@ -33,77 +44,23 @@ export const App: React.FC = () => { | |
| </div> | ||
|
|
||
| {/* Move this markup to Pagination */} | ||
| <ul className="pagination"> | ||
| <li className="page-item disabled"> | ||
| <a | ||
| data-cy="prevLink" | ||
| className="page-link" | ||
| href="#prev" | ||
| aria-disabled="true"> | ||
| « | ||
| </a> | ||
| </li> | ||
| <li className="page-item active"> | ||
| <a data-cy="pageLink" className="page-link" href="#1"> | ||
| 1 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#2"> | ||
| 2 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#3"> | ||
| 3 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#4"> | ||
| 4 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#5"> | ||
| 5 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#6"> | ||
| 6 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#7"> | ||
| 7 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#8"> | ||
| 8 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a data-cy="pageLink" className="page-link" href="#9"> | ||
| 9 | ||
| </a> | ||
| </li> | ||
| <li className="page-item"> | ||
| <a | ||
| data-cy="nextLink" | ||
| className="page-link" | ||
| href="#next" | ||
| aria-disabled="false"> | ||
| » | ||
| </a> | ||
| </li> | ||
| </ul> | ||
| <Pagination | ||
| total={items.length} // total number of items to paginate | ||
| perPage={perPage} // number of items per page | ||
| currentPage={currentPage} /* optional with 1 by default */ | ||
| onPageChange={setCurrentPage} | ||
| /> | ||
|
|
||
| <ul> | ||
| <li data-cy="item">Item 1</li> | ||
| <li data-cy="item">Item 2</li> | ||
| <li data-cy="item">Item 3</li> | ||
| <li data-cy="item">Item 4</li> | ||
| <li data-cy="item">Item 5</li> | ||
| {items | ||
| .slice((currentPage - 1) * perPage, currentPage * perPage) | ||
| .map(item => { | ||
| return ( | ||
| <li key={item} data-cy="item"> | ||
| {item} | ||
| </li> | ||
| ); | ||
| })} | ||
| </ul> | ||
| </div> | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,90 @@ | ||
| export const Pagination = () => {}; | ||
| import cn from 'classnames'; | ||
| import { getNumbers } from '../../utils'; | ||
|
|
||
| type Props = { | ||
| total: number; | ||
| perPage: number; | ||
| currentPage?: number; | ||
| onPageChange: (page: number) => void; | ||
| }; | ||
|
|
||
| export const Pagination = ({ | ||
| total, | ||
| perPage, | ||
| currentPage = 1, | ||
| onPageChange, | ||
| }: Props) => { | ||
|
Comment on lines
+11
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent work on making the |
||
| const pagesCount = Math.ceil(total / perPage); | ||
| const items = getNumbers(1, pagesCount); | ||
|
|
||
| const handlePrevClick = (event: React.MouseEvent<HTMLAnchorElement>) => { | ||
| event.preventDefault(); | ||
| if (currentPage && currentPage > 1) { | ||
| onPageChange(currentPage - 1); | ||
| } | ||
| }; | ||
|
|
||
| const handleNextClick = (event: React.MouseEvent<HTMLAnchorElement>) => { | ||
| event.preventDefault(); | ||
| if (currentPage && currentPage < pagesCount) { | ||
| onPageChange(currentPage + 1); | ||
| } | ||
| }; | ||
|
|
||
| const handlePageClick = ( | ||
| event: React.MouseEvent<HTMLAnchorElement>, | ||
| pageNumber: number, | ||
| ) => { | ||
| event.preventDefault(); | ||
|
|
||
| if (pageNumber !== currentPage) { | ||
| onPageChange(pageNumber); | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <ul className="pagination"> | ||
| <li className={cn('page-item', { disabled: currentPage === 1 })}> | ||
| <a | ||
| data-cy="prevLink" | ||
| className="page-link" | ||
| href="#prev" | ||
| aria-disabled={currentPage === 1} | ||
| onClick={handlePrevClick} | ||
| > | ||
| « | ||
| </a> | ||
| </li> | ||
| {items.map(n => ( | ||
| <li | ||
| key={n} | ||
| className={cn('page-item', { | ||
| active: currentPage === n, | ||
| disabled: n === currentPage, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The requirements state that the current page's
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Це ж додано, щоб візуально виділити не клікабельний стан |
||
| })} | ||
| > | ||
| <a | ||
| data-cy="pageLink" | ||
| className="page-link" | ||
| href={`#${n}`} | ||
| onClick={event => handlePageClick(event, n)} | ||
| > | ||
| {n} | ||
| </a> | ||
| </li> | ||
| ))} | ||
|
|
||
| <li className={cn('page-item', { disabled: currentPage === pagesCount })}> | ||
| <a | ||
| data-cy="nextLink" | ||
| className="page-link" | ||
| href="#next" | ||
| aria-disabled={currentPage === pagesCount} | ||
| onClick={handleNextClick} | ||
| > | ||
| » | ||
| </a> | ||
| </li> | ||
| </ul> | ||
| ); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The task requires using React Router to manage the
pageandperPagevalues in the URL. Currently, the state is initialized with static values. You should read these values from the URL's query parameters on page load to properly apply them.