Skip to content

Solution#1472

Open
tavokina wants to merge 3 commits into
mate-academy:masterfrom
tavokina:develop
Open

Solution#1472
tavokina wants to merge 3 commits into
mate-academy:masterfrom
tavokina:develop

Conversation

@tavokina
Copy link
Copy Markdown

@tavokina tavokina commented Apr 5, 2026

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

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

Review Summary

Great work on implementing the pagination feature! The component is well-structured and most of the functionality is working correctly. However, a couple of changes are needed in src/components/Pagination/Pagination.tsx to fully align with the task requirements.

First, the currentPage prop is defined as required, but the task specifies it should be optional with a default value of 1. You can fix this by making it optional in the PaginationProps interface (e.g., currentPage?: number) and setting a default value within the component.

Second, the onPageChange callback should only be triggered when the page number actually changes. Currently, it fires even when clicking on the active page. Please add a condition to ensure the callback is only invoked when the selected page is different from currentPage.

Addressing these points will make your solution fully compliant. Keep up the great work!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment thread src/App.tsx
Comment on lines 3 to 8
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}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

According to the requirements, the currentPage prop should be optional with a default value of 1. Currently, it's defined as a required prop in the PaginationProps interface. You can make it optional in the interface (e.g., currentPage?: number) and then provide a default value within the component.

Comment thread src/App.tsx
return (
<div className="container">
<h1>Items with Pagination</h1>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The task requires the onPageChange callback to be triggered only if the page was changed. Currently, clicking on the active page link will still call this function. You should add a condition to call onPageChange only when the selected page is different from the currentPage.


interface PaginationProps {
perPage: number;
currentPage: number;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The task description specifies that the currentPage prop should be optional with a default value of 1. Here, it is defined as a required prop. You can make it optional in the PaginationProps interface (e.g., currentPage?: number) and then provide a default value when destructuring the component's props.

data-cy="pageLink"
className="page-link"
href={`#${page}`}
onClick={() => onPageChange(page)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The onPageChange callback is triggered even when clicking on the currently active page. The requirements state it should be triggered "only if page was changed". You should add a condition to call onPageChange only when the selected page is different from currentPage.

data-cy="pageLink"
className="page-link"
href={`#${page}`}
onClick={() => onPageChange(page)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's a good practice to prevent the default browser action for <a> tag clicks when handling navigation with JavaScript. This will stop the URL from being updated with the href hash (e.g., #2). You can achieve this by using the event object in your onClick handler and calling event.preventDefault(). This applies to all page links, including the "previous" and "next" buttons.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

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

Review Summary

Great job implementing the pagination logic and the per-page selector! The core functionality is working well.

However, changes are needed because a key requirement is missing: the pagination state (page and perPage) is not synchronized with the browser's URL. Currently, if you refresh the page, the selected page and items per page are lost.

To fix this, please update the App.tsx component to:

  1. Read the page and perPage values from the URL's query parameters on initial load.
  2. Update the URL whenever the page or the number of items per page changes.

The useSearchParams hook from react-router-dom is the perfect tool for this. Keep up the great work!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment on lines +12 to +13
currentPage = 1,
total,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

According to the task description, page and perPage should be stored in the URL. On page load, their values should be read from the URL query parameters. When they change, the URL should be updated. Consider using the useSearchParams hook from react-router-dom to manage this.

Comment thread src/App.tsx Outdated
Comment on lines +13 to +14
const [elementsPerPage, setElementsPerPage] = useState<PerPageType>(5);
const [currentPage, setCurrentPage] = useState(1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

According to the requirements, the current page and items per page should be stored in the URL (e.g., ?page=2&perPage=5). Currently, the component uses local state that isn't synchronized with the URL.

You should use the useSearchParams hook from react-router-dom to:

  1. Read the page and perPage values from the URL when the component first loads to initialize the state.
  2. Update the URL search parameters whenever currentPage or elementsPerPage changes.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

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

Review Summary

Excellent work implementing the URL synchronization for the pagination state! You've correctly used useSearchParams and addressed the main feedback from the previous review.

I am approving this solution to help you progress, but there's an important improvement to consider for future projects. The component doesn't currently validate the page and perPage values from the URL. This can lead to unexpected behavior if a user enters an out-of-bounds page number (e.g., ?page=99) or an unsupported perPage value. Always validating external inputs makes your application more robust and user-friendly. Also, a small tip: the check for disabling the 'next' button would be more resilient if it used >= instead of == to handle cases where the page number from the URL is already too high.

Overall, you've made fantastic progress. Keep up the great work!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Footnotes

  1. Rate AI review example

Comment on lines +15 to +18
}) => {
const totalPages = Math.ceil(total / perPage);
const pageSelector = getNumbers(1, totalPages).map(page => (
<li
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The component correctly reads page and perPage from the URL, but it doesn't validate these values. This can lead to a couple of issues:

  1. If the URL has a perPage value that isn't in perPageOptions (e.g., ?perPage=7), the select element won't display it correctly, and the type assertion as PerPageType is unsafe.
  2. If the URL has a page value that is out of bounds (e.g., ?page=99), the component will show an empty list of items.

It's best practice to validate input from external sources like URLs. You should check if perPageFromURL is a valid option and clamp pageFromURL to be within the valid page range (1 to totalPages).

{pageSelector}

<li
className={`page-item ${currentPage === totalPages ? 'disabled' : ''}`}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This check for disabling the 'next' button should use >= (i.e., currentPage >= totalPages). If currentPage is greater than totalPages (for example, from a URL parameter), this check fails, and the button remains enabled.

The same change is needed for the aria-disabled attribute on line 70 and in the onClick handler on line 73 to make the component robust against out-of-bounds page numbers.

Comment thread src/App.tsx
Comment on lines +15 to +18
const pageFromURL = Number(searchParams.get('page')) || 1;
const perPageFromURL = Number(searchParams.get('perPage')) || 5;
const [currentPage, setCurrentPage] = useState(pageFromURL);
const [elementsPerPage, setElementsPerPage] = useState<PerPageType>(perPageFromURL as PerPageType);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's great that you're reading the page and perPage values from the URL. However, the current implementation doesn't validate these values before using them to initialize the state.

For example:

  1. If the URL has ?perPage=7, elementsPerPage becomes 7. This is not a valid option in the <select> dropdown, which can be confusing for the user. It's better to ensure the perPage value is one of the allowed options.
  2. If the URL has a page number that is out of bounds (e.g., ?page=100 when there are only 9 pages), the component will show an empty list of items and potentially confusing info text.

Consider adding validation for page and perPage from the URL to ensure they fall within a valid range before setting the state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants