Multi-file games lists, clicking a game leads to mod search for that game, search redirects, pagination optimizations #38

Merged
freakoverse merged 11 commits from staging into master 2024-09-18 19:30:26 +00:00
2 changed files with 134 additions and 57 deletions
Showing only changes of commit 05414013ce - Show all commits

View File

@ -38,3 +38,101 @@ export const Pagination = React.memo(
)
}
)
type PaginationWithPageNumbersProps = {
currentPage: number
totalPages: number
handlePageChange: (page: number) => void
}
export const PaginationWithPageNumbers = ({
currentPage,
totalPages,
handlePageChange
}: PaginationWithPageNumbersProps) => {
// Function to render the pagination controls with page numbers
const renderPagination = () => {
const pagesToShow = 5 // Number of page numbers to show around the current page
const pageNumbers: (number | string)[] = [] // Array to store page numbers and ellipses
// Case when the total number of pages is less than or equal to the limit
if (totalPages <= pagesToShow + 2) {
for (let i = 1; i <= totalPages; i++) {
pageNumbers.push(i) // Add all pages to the pagination
}
} else {
// Add the first page (always visible)
pageNumbers.push(1)
// Calculate the range of pages to show around the current page
const startPage = Math.max(2, currentPage - Math.floor(pagesToShow / 2))
const endPage = Math.min(
totalPages - 1,
currentPage + Math.floor(pagesToShow / 2)
)
// Add ellipsis if there are pages between the first page and the startPage
if (startPage > 2) pageNumbers.push('...')
// Add the pages around the current page
for (let i = startPage; i <= endPage; i++) {
pageNumbers.push(i)
}
// Add ellipsis if there are pages between the endPage and the last page
if (endPage < totalPages - 1) pageNumbers.push('...')
// Add the last page (always visible)
pageNumbers.push(totalPages)
}
// Map over the array and render each page number or ellipsis
return pageNumbers.map((page, index) => {
if (typeof page === 'number') {
// For actual page numbers, render clickable boxes
return (
<div
key={index}
className={`PaginationMainInsideBox ${
currentPage === page ? 'PMIBActive' : '' // Highlight the current page
}`}
onClick={() => handlePageChange(page)} // Navigate to the selected page
>
<p>{page}</p>
</div>
)
} else {
// For ellipses, render non-clickable dots
return (
<p key={index} className='PaginationMainInsideBox PMIBDots'>
...
</p>
)
}
})
}
return (
<div className='IBMSecMain'>
<div className='PaginationMain'>
<div className='PaginationMainInside'>
<div
className='PaginationMainInsideBox PaginationMainInsideBoxArrows'
onClick={() => handlePageChange(currentPage - 1)}
>
<i className='fas fa-chevron-left'></i>
</div>
<div className='PaginationMainInsideBoxGroup'>
{renderPagination()}
</div>
<div
className='PaginationMainInsideBox PaginationMainInsideBoxArrows'
onClick={() => handlePageChange(currentPage + 1)}
>
<i className='fas fa-chevron-right'></i>
</div>
</div>
</div>
</div>
)
}

View File

@ -1,9 +1,29 @@
import '../styles/pagination.css'
import '../styles/styles.css'
import '../styles/search.css'
import { PaginationWithPageNumbers } from 'components/Pagination'
import { MAX_GAMES_PER_PAGE } from 'constants.ts'
import { useGames } from 'hooks'
import { useState } from 'react'
import { GameCard } from '../components/GameCard'
import '../styles/pagination.css'
import '../styles/search.css'
import '../styles/styles.css'
export const GamesPage = () => {
const games = useGames()
const [currentPage, setCurrentPage] = useState(1)
// Pagination logic
const totalGames = games.length
const totalPages = Math.ceil(totalGames / MAX_GAMES_PER_PAGE)
const startIndex = (currentPage - 1) * MAX_GAMES_PER_PAGE
const endIndex = startIndex + MAX_GAMES_PER_PAGE
const currentGames = games.slice(startIndex, endIndex)
const handlePageChange = (page: number) => {
if (page >= 1 && page <= totalPages) {
setCurrentPage(page)
}
}
return (
<div className='InnerBodyMain'>
<div className='ContainerMain'>
@ -11,7 +31,7 @@ export const GamesPage = () => {
<div className='IBMSecMain'>
<div className='SearchMainWrapper'>
<div className='IBMSMTitleMain'>
<h2 className='IBMSMTitleMainHeading'>Games (WIP)</h2>
<h2 className='IBMSMTitleMainHeading'>Games</h2>
</div>
<div className='SearchMain'>
<div className='SearchMainInside'>
@ -35,61 +55,20 @@ export const GamesPage = () => {
</div>
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMList IBMSMListFeaturedAlt'>
{currentGames.map((game) => (
<GameCard
title='This is a game title, the best game title'
imageUrl='/assets/img/DEGMods%20Placeholder%20Img.png'
key={game['Game Name']}
title={game['Game Name']}
imageUrl={game['Boxart image']}
/>
<GameCard
title='This is a game title, the best game title'
imageUrl='/assets/img/DEGMods%20Placeholder%20Img.png'
))}
</div>
</div>
<PaginationWithPageNumbers
currentPage={currentPage}
totalPages={totalPages}
handlePageChange={handlePageChange}
/>
<GameCard
title='This is a game title, the best game title'
imageUrl='/assets/img/DEGMods%20Placeholder%20Img.png'
/>
<GameCard
title='This is a game title, the best game title'
imageUrl='/assets/img/DEGMods%20Placeholder%20Img.png'
/>
<GameCard
title='This is a game title, the best game title'
imageUrl='/assets/img/DEGMods%20Placeholder%20Img.png'
/>
</div>
</div>
<div className='IBMSecMain'>
<div className='PaginationMain'>
<div className='PaginationMainInside'>
<a
className='PaginationMainInsideBox PaginationMainInsideBoxArrows'
href='#'
>
<i className='fas fa-chevron-left'></i>
</a>
<div className='PaginationMainInsideBoxGroup'>
<a className='PaginationMainInsideBox PMIBActive' href='#'>
<p>1</p>{' '}
</a>
<a className='PaginationMainInsideBox' href='#'>
<p>2</p>{' '}
</a>
<a className='PaginationMainInsideBox' href='#'>
<p>3</p>
</a>
<p className='PaginationMainInsideBox PMIBDots'>...</p>
<a className='PaginationMainInsideBox' href='#'>
<p>8</p>
</a>
</div>
<a
className='PaginationMainInsideBox PaginationMainInsideBoxArrows'
href='#'
>
<i className='fas fa-chevron-right'></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>