-
-
Notifications
You must be signed in to change notification settings - Fork 753
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
feat: add pagination feature in blog page #3595
base: master
Are you sure you want to change the base?
Conversation
WalkthroughThe pull request introduces a comprehensive pagination system for the blog page. The implementation includes creating helper functions like Changes
Assessment against linked issues
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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.
Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.
✅ Deploy Preview for asyncapi-website ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
Hello, @coderabbitai[bot]! 👋🏼
|
@asyncapi-bot i'll start reviewing the changes for the pagination feature implementation. 🔗 analysis chain 🏁 scripts executed the following scripts were executed for the analysis: script:
length of output: 9907 ✅ Actions performedReview triggered.
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #3595 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 20 20
Lines 732 732
=========================================
Hits 732 732 ☔ View full report in Codecov by Sentry. |
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-3595--asyncapi-website.netlify.app/ |
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.
Actionable comments posted: 1
🧹 Nitpick comments (6)
components/helpers/applyFilter.ts (1)
140-142
: Consider filtering out pagination params before processing.While the current implementation works correctly by skipping the 'page' parameter, consider a more maintainable approach by filtering out pagination-related parameters before processing.
Here's a suggested improvement:
export const onFilterApply = ( inputData: DataObject[], onFilter: (result: DataObject[], query: Filter) => void, query: Filter ): void => { let result = inputData; if (query && Object.keys(query).length >= 1) { - Object.keys(query).forEach((property) => { - if (property === 'page') { - return; - } + // Filter out pagination params + const filterParams = Object.keys(query).filter(key => key !== 'page'); + filterParams.forEach((property) => { const res = result.filter((e) => { // ... rest of the filtering logic }); result = res; }); } onFilter(result, query); };This approach:
- Makes the intention clearer by explicitly filtering out pagination params
- Avoids using early returns within forEach
- Is more extensible if more pagination-related params need to be excluded in the future
components/pagination/PaginationItem.tsx (1)
4-5
: Remove unnecessary eslint-disable comment.The empty eslint-disable comment can be removed as it serves no purpose.
- // eslint-disable-next-line prettier/prettier
components/helpers/usePagination.ts (1)
14-30
: Add input validation for edge cases.While the implementation is solid, consider adding validation for:
- Negative or zero itemsPerPage
- Empty items array
export function usePagination<T>(items: T[], itemsPerPage: number) { + if (itemsPerPage <= 0) { + throw new Error('itemsPerPage must be greater than 0'); + } + const [currentPage, setCurrentPage] = useState(1); - const maxPage = Math.ceil(items.length / itemsPerPage); + const maxPage = items.length ? Math.ceil(items.length / itemsPerPage) : 1;components/pagination/Pagination.tsx (2)
6-7
: Remove unnecessary eslint-disable comment.The empty eslint-disable comment can be removed as it serves no purpose.
- // eslint-disable-next-line prettier/prettier
55-75
: Enhance accessibility and reduce CSS duplication.
- Add aria-labels to SVG elements for better accessibility
- Extract duplicate button styles to a common class
+const commonButtonStyles = ` + font-normal flex h-[34px] items-center justify-center gap-2 rounded bg-white px-4 + py-[7px] text-sm leading-[17px] tracking-[-0.01em] +`; {/* Previous button */} <button onClick={() => handlePageChange(currentPage - 1)} disabled={currentPage === 1} - className={` - font-normal flex h-[34px] items-center justify-center gap-2 rounded bg-white px-4 - py-[7px] text-sm leading-[17px] tracking-[-0.01em] + className={`${commonButtonStyles} ${currentPage === 1 ? 'cursor-not-allowed text-gray-300' : 'text-[#141717] hover:bg-gray-50'} `} + aria-label="Previous page" > <svg width='20' height='20' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' className='stroke-current' + aria-hidden="true" > {/* Next button */} <button onClick={() => handlePageChange(currentPage + 1)} disabled={currentPage === totalPages} - className={` - font-normal flex h-[34px] items-center justify-center gap-2 rounded bg-white px-4 - py-[7px] text-sm leading-[17px] tracking-[-0.01em] + className={`${commonButtonStyles} ${currentPage === totalPages ? 'cursor-not-allowed text-gray-300' : 'text-[#141717] hover:bg-gray-50'} `} + aria-label="Next page" >Also applies to: 99-119
pages/blog/index.tsx (1)
43-56
: Add scroll to top behavior on page change.When navigating between pages, consider scrolling to the top for better user experience.
const handlePageChange = (page: number) => { setCurrentPage(page); const currentFilters = { ...router.query, page: page.toString() }; router.push( { pathname: router.pathname, query: currentFilters }, undefined, { shallow: true } - ); + ).then(() => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }); };
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
components/helpers/applyFilter.ts
(1 hunks)components/helpers/usePagination.ts
(1 hunks)components/pagination/Pagination.tsx
(1 hunks)components/pagination/PaginationItem.tsx
(1 hunks)pages/blog/index.tsx
(3 hunks)
🔇 Additional comments (3)
components/pagination/PaginationItem.tsx (1)
19-31
: Great implementation with accessibility in mind!The component is well-structured with:
- Clear prop types and documentation
- Proper accessibility attributes (aria-current)
- Semantic button element with appropriate styling
components/pagination/Pagination.tsx (1)
21-122
: Well-implemented pagination logic!The component demonstrates:
- Smart handling of different page number scenarios
- Clean separation of concerns
- Proper validation in handlePageChange
pages/blog/index.tsx (1)
154-168
: Well-integrated pagination system!The pagination integration demonstrates:
- Clean integration with the existing blog page
- Proper state management
- Good user experience with loading states
pages/blog/index.tsx
Outdated
useEffect(() => { | ||
const pageFromQuery = parseInt(router.query.page as string, 10); | ||
|
||
if (!Number.isNaN(pageFromQuery) && pageFromQuery >= 1 && pageFromQuery !== currentPage) { | ||
setCurrentPage(pageFromQuery); | ||
} | ||
}, [router.query.page]); |
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.
🛠️ Refactor suggestion
Add error handling for invalid page numbers.
When an invalid page number is provided in the URL, the code should handle it gracefully.
useEffect(() => {
const pageFromQuery = parseInt(router.query.page as string, 10);
- if (!Number.isNaN(pageFromQuery) && pageFromQuery >= 1 && pageFromQuery !== currentPage) {
+ if (!Number.isNaN(pageFromQuery)) {
+ if (pageFromQuery >= 1 && pageFromQuery <= maxPage && pageFromQuery !== currentPage) {
setCurrentPage(pageFromQuery);
+ } else {
+ // Reset to page 1 for invalid page numbers
+ handlePageChange(1);
+ }
}
- }, [router.query.page]);
+ }, [router.query.page, maxPage]);
Committable suggestion skipped: line range outside the PR's diff.
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.
Thank you for the suggestion to add error handling for invalid page numbers. I implemented the proposed code, but I am encountering an issue where navigating to any page (e.g., ?page=2) redirects me back to ?page=1.
It seems like the handlePageChange(1) function is being triggered unnecessarily, even when the pageFromQuery is valid.
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.
@priyanshuxkumar I understand the issue. The problem occurs because we're validating against maxPage
before it's properly initialized. Let's modify the code to ensure we only validate when we have a valid maxPage
:
useEffect(() => {
const pageFromQuery = parseInt(router.query.page as string, 10);
if (!Number.isNaN(pageFromQuery) && maxPage > 0) {
if (pageFromQuery >= 1 && pageFromQuery <= maxPage && pageFromQuery !== currentPage) {
setCurrentPage(pageFromQuery);
} else if (pageFromQuery < 1 || pageFromQuery > maxPage) {
// Only reset to page 1 if the page number is actually invalid
handlePageChange(1);
}
}
}, [router.query.page, maxPage, currentPage]);
This should fix the issue by:
- Only performing validation when
maxPage
is properly initialized (maxPage > 0
) - Only resetting to page 1 when the page number is actually out of bounds
Let me know if this resolves the issue!
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.
yes its resolved
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.
@priyanshuxkumar Great to hear that the pagination is working correctly now! 🎉
If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!
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.
Actionable comments posted: 0
🧹 Nitpick comments (3)
pages/blog/index.tsx (3)
40-41
: Consider moving postsPerPage to configuration.The hardcoded value of 9 posts per page would be better managed as a configuration constant, making it easier to adjust across different viewports or requirements.
+// Add to src/config/blog.ts or similar +export const POSTS_PER_PAGE = 9; + // In BlogIndexPage - const postsPerPage = 9; + const postsPerPage = POSTS_PER_PAGE;
164-168
: Improve loader condition logic.The current loader condition might show unnecessarily when
currentItems
is empty butposts
exist. Consider checking both arrays.- {Object.keys(currentItems).length > 0 && !isClient && ( + {Object.keys(posts).length > 0 && !isClient && (
169-173
: Enhance pagination container accessibility.Add appropriate ARIA attributes to improve accessibility for screen readers.
- <div className='mt-8 w-full'> + <div className='mt-8 w-full' role="navigation" aria-label="Blog posts pagination">
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
pages/blog/index.tsx
(3 hunks)
⏰ Context from checks skipped due to timeout of 180000ms (1)
- GitHub Check: Test NodeJS PR - macos-13
🔇 Additional comments (2)
pages/blog/index.tsx (2)
4-4
: LGTM! Import statements are well-organized.The new imports for pagination components follow the existing import structure and use proper path aliases.
Also applies to: 10-10
43-69
: Well-implemented page change handling and URL synchronization!The code effectively:
- Updates page state
- Synchronizes URL query parameters
- Handles invalid page numbers gracefully
- Uses shallow routing for better performance
Hi @akshatnema and @Mayaleeeee, It seems that the "Notify Triagers" workflow is failing with the following error: |
Description
Add pagination feature in Blog page
Related issue(s)
Fixes #3570
update.mp4
Related issue(s)
Summary by CodeRabbit
Release Notes
New Features
PaginationItem
component for individual page numbersImprovements
Technical Enhancements