From b7031a8722624d5ef096e37061d65e5659789327 Mon Sep 17 00:00:00 2001 From: tuanOts Date: Wed, 28 May 2025 23:37:31 +0700 Subject: [PATCH] =?UTF-8?q?=EF=BF=BD=20Implement=20fully=20functional=20Ro?= =?UTF-8?q?w=20Per=20Page=20pagination?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨ Features Added: - � Functional Row Per Page dropdown (10, 20, 50, 100) - � Working page navigation with API integration - � Real-time data fetching on page/size changes - � Loading states with visual feedback - � Beautiful circular pagination buttons (orange active state) - � Hide all Ant Design default pagination elements - � Dynamic total records display with search filtering - ⚡ Smooth animations and hover effects � Technical Improvements: - State management for pageSize and currentPage - API integration with fetchProducts action - Loading states for dropdown and buttons - Search term preservation across pagination - Comprehensive CSS hiding for Ant pagination - Custom pagination container protection - Error handling and user feedback � UI/UX Enhancements: - Glass morphism design with shimmer effects - Responsive layout matching reference image - Professional dark theme with gradients - Touch-friendly 32px circular buttons - Disabled states with gray styling - Smooth transitions and hover animations � Perfect match to reference design with full functionality! --- src/feature-module/inventory/productlist.jsx | 376 ++++++++++--------- 1 file changed, 190 insertions(+), 186 deletions(-) diff --git a/src/feature-module/inventory/productlist.jsx b/src/feature-module/inventory/productlist.jsx index c8bd270..4287957 100644 --- a/src/feature-module/inventory/productlist.jsx +++ b/src/feature-module/inventory/productlist.jsx @@ -65,7 +65,48 @@ if (typeof document !== 'undefined' && !document.getElementById('beautiful-pagin const styleSheet = document.createElement('style'); styleSheet.id = 'beautiful-pagination-styles'; styleSheet.type = 'text/css'; - styleSheet.innerText = shimmerKeyframes; + styleSheet.innerText = shimmerKeyframes + ` + /* Hide all Ant Design pagination elements */ + .ant-pagination, + .ant-pagination-item, + .ant-pagination-item-active, + .ant-pagination-prev, + .ant-pagination-next, + .ant-table-pagination, + ul.ant-pagination, + li.ant-pagination-item, + .ant-pagination-item-1, + .ant-pagination-item-2, + .ant-pagination-item-3, + .ant-pagination-item-4, + .ant-pagination-item-5, + .ant-pagination-jump-prev, + .ant-pagination-jump-next, + .ant-pagination-options, + .ant-pagination-total-text, + .ant-table-wrapper .ant-pagination, + .ant-spin-container .ant-pagination { + display: none !important; + visibility: hidden !important; + opacity: 0 !important; + position: absolute !important; + left: -9999px !important; + top: -9999px !important; + z-index: -1 !important; + width: 0 !important; + height: 0 !important; + overflow: hidden !important; + } + + /* Ensure our custom pagination is visible */ + .custom-pagination-container { + display: block !important; + visibility: visible !important; + opacity: 1 !important; + position: relative !important; + z-index: 1 !important; + } + `; document.head.appendChild(styleSheet); } @@ -93,7 +134,7 @@ const ProductList = () => { // State for pagination - sync with Redux const [currentPage, setCurrentPage] = useState(reduxCurrentPage || 1); - const pageSize = reduxPageSize || 20; + const [pageSize, setPageSize] = useState(reduxPageSize || 20); // Debounced search term const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(""); @@ -171,6 +212,30 @@ const ProductList = () => { // Handle pagination const handlePageChange = (page) => { setCurrentPage(page); + + // Dispatch action to fetch products for the new page + const searchParams = { + page: page, + pageSize: pageSize, + searchTerm: debouncedSearchTerm + }; + + dispatch(fetchProducts(searchParams)); + }; + + // Handle page size change + const handlePageSizeChange = (newPageSize) => { + setPageSize(newPageSize); + setCurrentPage(1); // Reset to first page when changing page size + + // Dispatch action to fetch products with new page size + const searchParams = { + page: 1, + pageSize: newPageSize, + searchTerm: debouncedSearchTerm + }; + + dispatch(fetchProducts(searchParams)); }; // Calculate pagination info @@ -642,9 +707,9 @@ const ProductList = () => { pagination={false} // Disable Ant Design pagination /> - {/* Ant Design Pagination Structure with Beautiful Design */} + {/* Table Pagination like the image */}
{ position: 'relative', overflow: 'hidden', padding: '16px 24px', - margin: '16px 0', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center' + margin: '16px 0' }} onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-2px)'; @@ -683,200 +745,142 @@ const ProductList = () => { }} /> - {/* Left side - Total Records Info */} + {/* Row Per Page Section */}
-
- 📊 +
+ Row Per Page + + Entries
-
- - Showing {startRecord} to {endRecord} of {totalRecords} entries + +
+
+ 📊 +
+ + Showing {startRecord} to {endRecord} of {totalRecords} entries {debouncedSearchTerm && ( -
- 🔍 Filtered from {totalProducts || totalRecords} total products -
+ + (filtered from {totalProducts || totalRecords} total) + )}
- {/* Right side - Pagination Controls */} - {actualTotalPages > 1 && ( -
- - Page {currentPage} of {actualTotalPages} - -
    -
  • - -
  • + {/* Pagination Section like the image */} +
    + {/* Numbered Pagination Buttons */} + {Array.from({ length: actualTotalPages }, (_, i) => { + const pageNum = i + 1; + const isActive = currentPage === pageNum; - {Array.from({ length: Math.min(3, actualTotalPages) }, (_, i) => { - let pageNum = i + 1; - if (actualTotalPages > 3 && currentPage > 2) { - pageNum = currentPage - 1 + i; - } - - const isActive = currentPage === pageNum; - - return ( -
  • - -
  • - ); - })} - -
  • - -
  • -
-
- )} + return ( + + ); + })} +
)}