diff --git a/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx b/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx index 63ffd35c82..73c9370959 100644 --- a/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx +++ b/src/components/CommunityPortal/Reports/Participation/DropOffTracking.jsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useMemo, useEffect } from 'react'; import { useSelector } from 'react-redux'; import styles from './Participation.module.css'; import mockEvents from './mockData'; @@ -6,6 +6,10 @@ import mockEvents from './mockData'; function DropOffTracking() { const [selectedEvent, setSelectedEvent] = useState('All Events'); const [selectedTime, setSelectedTime] = useState('All Time'); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(20); + + const PAGE_SIZE_OPTIONS = [10, 20, 50]; const getDateRange = () => { const today = new Date(); @@ -44,6 +48,62 @@ function DropOffTracking() { return true; }); + useEffect(() => { + setCurrentPage(1); + }, [selectedEvent, selectedTime]); + + const paginatedEvents = useMemo(() => { + const startIndex = (currentPage - 1) * pageSize; + const endIndex = startIndex + pageSize; + + return filteredEvents.slice(startIndex, endIndex); + }, [filteredEvents, currentPage, pageSize]); + + const totalPages = Math.ceil(filteredEvents.length / pageSize); + const showPagination = totalPages > 1; + + const handlePageSizeChange = e => { + setPageSize(Number(e.target.value)); + setCurrentPage(1); + }; + + const handlePreviousPage = () => { + setCurrentPage(prev => Math.max(prev - 1, 1)); + }; + + const handleNextPage = () => { + setCurrentPage(prev => Math.min(prev + 1, totalPages)); + }; + + const getVisiblePages = () => { + const pages = []; + + if (totalPages <= 7) { + return Array.from({ length: totalPages }, (_, i) => i + 1); + } + + const leftBound = Math.max(2, currentPage - 1); + const rightBound = Math.min(totalPages - 1, currentPage + 1); + + pages.push(1); + + if (currentPage > 3) { + pages.push('left-ellipsis'); + } + + for (let i = leftBound; i <= rightBound; i++) { + pages.push(i); + } + + if (currentPage < totalPages - 2) { + pages.push('right-ellipsis'); + } + + pages.push(totalPages); + + return pages; + }; + const darkMode = useSelector(state => state.theme.darkMode); return ( @@ -109,17 +169,90 @@ function DropOffTracking() { - {filteredEvents.map(event => ( + {paginatedEvents.map(event => ( {event.eventName} - {event.noShowRate} - {event.dropOffRate} + {event.noShowRate} + {event.dropOffRate} {event.attendees} ))} + + {/*Pagination*/} + {showPagination && ( +
+
+ Showing {(currentPage - 1) * pageSize + 1} to{' '} + {Math.min(currentPage * pageSize, filteredEvents.length)} of {filteredEvents.length}{' '} + records +
+ +
+ + +
+ {getVisiblePages().map(page => + page === 'left-ellipsis' || page === 'right-ellipsis' ? ( + + ... + + ) : ( + + ), + )} +
+ + + Page {currentPage} of {totalPages} + + + +
+ +
+ + +
+
+ )} ); } diff --git a/src/components/CommunityPortal/Reports/Participation/Participation.module.css b/src/components/CommunityPortal/Reports/Participation/Participation.module.css index d250be26a1..94220890ab 100644 --- a/src/components/CommunityPortal/Reports/Participation/Participation.module.css +++ b/src/components/CommunityPortal/Reports/Participation/Participation.module.css @@ -294,6 +294,7 @@ border-radius: 10px; padding: 10px; background: #fff; + margin-bottom: 20px; } .trackingListContainerDark { max-height: 600px; @@ -932,3 +933,161 @@ .insightsTabDarkMode:hover { background-color: #374151; } + +/* Pagination Styles */ +.paginationContainer { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; + border-top: 1px solid #e0e0e0; + margin-top: 16px; + gap: 16px; + flex-wrap: nowrap; + background-color: #f9f9f9; + border-radius: 4px; + width: 100%; +} + +.paginationContainerDark { + background-color: #1C2541; + border-top: 1px solid #3A506B; +} + +.paginationInfo { + font-size: 14px; + color: #666; + min-width: 200px; +} + +.paginationContainerDark .paginationInfo { + color: #aaa; +} + +.paginationControls { + display: flex; + gap: 12px; + align-items: center; +} + +.paginationControls button { + padding: 8px 16px; + border: 1px solid #ccc; + background-color: white; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + transition: all 0.2s ease; +} + +.paginationControls button:hover:not(:disabled) { + background-color: #f0f0f0; + border-color: #999; +} + +.paginationControls button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.paginationContainerDark .paginationControls button { + background-color: #3A506B; + border-color: #4A607B; + color: #ffffff; +} + +.paginationContainerDark .paginationControls button:hover:not(:disabled) { + background-color: #4A607B; + border-color: #5B708C; +} +.paginationButtonDark:hover:not(:disabled) { + background-color: #4a4a4a; + border-color: #777; +} +.paginationContainerDark .paginationControls button:disabled { + background-color: #2E3B4E; + border-color: #3A506B; + color: #C5D1E0; + opacity: 0.7; +} + +.pageIndicator { + font-size: 14px; + color: #666; + font-weight: 500; + min-width: 120px; + text-align: center; +} + +.paginationContainerDark .pageIndicator { + color: #aaa; +} + +.pageSizeSelector { + display: flex; + gap: 8px; + align-items: center; + min-width: 200px; + justify-content: flex-end; + white-space: nowrap; + flex-shrink: 0; +} + +.pageSizeSelector label { + font-size: 14px; + color: #666; +} + +.paginationContainerDark .pageSizeSelector label { + color: #aaa; +} + +.paginationContainerDark .pageSizeSelector select { + background-color: #3A506B; + border-color: #4A607B; + color: #ffffff; +} + +.pageSizeSelector select { + padding: 6px 12px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: white; + font-size: 14px; + cursor: pointer; +} + +.pageSizeSelectorDark select { + background-color: #3a3a3a; + border-color: #555; + color: #fff; +} + +.pageNumbers { + display: flex; + align-items: center; + gap: 6px; +} + +.pageNumberButton { + padding: 4px 10px; + border-radius: 4px; + border: 1px solid #ccc; + background: white; + cursor: pointer; +} + +.pageNumberButton:hover { + background: #f2f2f2; +} + +.activePage { + background: #1E40AF; + color: #ffffff; + border-color: #1E40AF; +} + +.ellipsis { + padding: 0 6px; + font-weight: bold; +} \ No newline at end of file