- Header/MobileBar: MenuRoot/Positioner/Content + Portal + Tooltip shims, ghost icon buttons, 2rem padded user/settings menus, hover token gray.700; MobileBar drawer API (open/onOpenChange/finalFocusEl) - FilterBar/ActiveFilters: DrawerRoot/CloseTrigger, Divider -> Separator, Tag shim, FixedSelect with typed handlers and width-preserving chakraStyles, blue active-filter pills untouched - Pagination: NumberInputRoot/Field + NativeSelect shims, first/last arrows back to double chevrons (LuChevronsLeft/Right), single chevrons kept for prev/next - Search/SearchModal, Home, NoGames, LoadingModal, DashboardLoadingModal: Dialog/Toaster-era props, gap/align/textAlign renames; App.test target content updated accordingly
214 lines
7.5 KiB
TypeScript
214 lines
7.5 KiB
TypeScript
import React from 'react'
|
|
import {
|
|
Flex,
|
|
Grid,
|
|
GridItem,
|
|
IconButton,
|
|
Text,
|
|
Portal,
|
|
} from '@chakra-ui/react'
|
|
import {NumberInputRoot, NumberInputField} from './ui/number-input'
|
|
import { NativeSelect } from '@chakra-ui/react'
|
|
import { LuChevronLeft, LuChevronRight, LuChevronsLeft, LuChevronsRight } from 'react-icons/lu'
|
|
import {Tooltip} from './ui/tooltip'
|
|
import { useHookstate } from '@hookstate/core'
|
|
import { gameDashboardState } from '../stateManagement/gameState'
|
|
import { loadingState } from '../stateManagement/loadingState'
|
|
import { adminMode } from '../stateManagement/userState'
|
|
import getWithFilters from '../componentUtils/getWithFilters'
|
|
import { ratingState, steamRatingState } from "../stateManagement/ratingState";
|
|
import {useColorModeValue} from "./ui/color-mode";
|
|
import {useMediaQuery} from "@chakra-ui/react";
|
|
|
|
export default function Pagination() {
|
|
const gamesState = useHookstate(gameDashboardState)
|
|
const games = gamesState.get()
|
|
const admin = useHookstate(adminMode).get()
|
|
const loadedState = useHookstate(loadingState)
|
|
const pageIndex = games.count.currentPage
|
|
const pageSize = games.count.limit
|
|
const pageCount = games.count.pages
|
|
const bg = useColorModeValue('gray.50', 'transparent')
|
|
const useRatingState = useHookstate(ratingState).get()
|
|
const useSteamRatingState = useHookstate(steamRatingState).get()
|
|
const [isSmallerThan768] = useMediaQuery(['(max-width: 768px)'])
|
|
|
|
const setPageSize = async (limit: number) => await getWithFilters(
|
|
gamesState,
|
|
loadedState,
|
|
admin,
|
|
games.count.currentPage,
|
|
limit,
|
|
games.searchParams,
|
|
games.filters,
|
|
useRatingState,
|
|
useSteamRatingState
|
|
)
|
|
|
|
const gotoPage = async (page: number) => await getWithFilters(
|
|
gamesState,
|
|
loadedState,
|
|
admin,
|
|
page,
|
|
games.count.limit,
|
|
games.searchParams,
|
|
games.filters,
|
|
useRatingState,
|
|
useSteamRatingState
|
|
)
|
|
|
|
const previousPage = async () => await getWithFilters(
|
|
gamesState,
|
|
loadedState,
|
|
admin,
|
|
games.pagination.prev.page,
|
|
games.count.limit,
|
|
games.searchParams,
|
|
games.filters,
|
|
useRatingState,
|
|
useSteamRatingState
|
|
)
|
|
|
|
const nextPage = async () => await getWithFilters(
|
|
gamesState,
|
|
loadedState,
|
|
admin,
|
|
games.pagination.next.page,
|
|
games.count.limit,
|
|
games.searchParams,
|
|
games.filters,
|
|
useRatingState,
|
|
useSteamRatingState
|
|
)
|
|
|
|
return (
|
|
<Grid mb={'6'} justifyItems={{
|
|
base: 'center'
|
|
}} alignItems={{
|
|
base: 'center'
|
|
}} templateAreas={{
|
|
base: `
|
|
"backArrows pageNumber forwardArrows"
|
|
"backArrows countPerPage forwardArrows"
|
|
"backArrows gamesFound forwardArrows"
|
|
`,
|
|
md: `"backArrows pageNumber goToPage countPerPage gamesFound forwardArrows"`
|
|
}}>
|
|
<GridItem area={"backArrows"}>
|
|
<Flex>
|
|
<Tooltip content="First Page">
|
|
<IconButton
|
|
aria-label={'First Page'}
|
|
onMouseDown={() => gotoPage(0)}
|
|
disabled={pageIndex <= 1}
|
|
mr={4}
|
|
>
|
|
<LuChevronsLeft />
|
|
</IconButton>
|
|
</Tooltip>
|
|
<Tooltip content="Previous Page">
|
|
<IconButton
|
|
aria-label={'Previous Page'}
|
|
onMouseDown={previousPage}
|
|
disabled={pageIndex <= 1}
|
|
>
|
|
<LuChevronLeft />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</Flex>
|
|
</GridItem>
|
|
<GridItem area={"pageNumber"}>
|
|
<Text mr={{ md: 8 }}>
|
|
Page{' '}
|
|
<Text fontWeight="bold" as="span">
|
|
{pageIndex}
|
|
</Text>{' '}
|
|
of{' '}
|
|
<Text fontWeight="bold" as="span">
|
|
{pageCount}
|
|
</Text>
|
|
</Text>
|
|
</GridItem>
|
|
{!isSmallerThan768 &&
|
|
<GridItem area={"goToPage"}>
|
|
<Text mb={'1'}>Go to Page:</Text>
|
|
<NumberInputRoot
|
|
bg={bg}
|
|
rounded={'md'}
|
|
w={{ base: 20, md: 28 }}
|
|
min={1}
|
|
max={pageCount}
|
|
value={String(pageIndex)}
|
|
onValueChange={(e) => {
|
|
const page = e.value ? Number(e.value) : 1
|
|
gotoPage(page)
|
|
}}
|
|
>
|
|
<NumberInputField
|
|
borderWidth="1px"
|
|
borderStyle="solid"
|
|
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
|
/>
|
|
</NumberInputRoot>
|
|
|
|
</GridItem>
|
|
}
|
|
<GridItem area={"countPerPage"}>
|
|
<Text mb={'1'}>Count Per Page:</Text>
|
|
<NativeSelect.Root
|
|
ml={{
|
|
base: '4',
|
|
md: '0'
|
|
}}
|
|
w={{ base: 20, md: 32 }}
|
|
>
|
|
<NativeSelect.Field
|
|
rounded={'md'}
|
|
borderWidth={'1px'}
|
|
borderStyle={'solid'}
|
|
borderColor={'gray.500'}
|
|
bg={bg}
|
|
value={pageSize}
|
|
onChange={(e: any) => {
|
|
setPageSize(Number(e.target.value))
|
|
}}
|
|
>
|
|
{[10, 20, 30, 40, 50].map((pageSize) => (
|
|
<option key={pageSize} value={pageSize}>
|
|
{pageSize}
|
|
</option>
|
|
))}
|
|
</NativeSelect.Field>
|
|
<NativeSelect.Indicator />
|
|
</NativeSelect.Root>
|
|
</GridItem>
|
|
<GridItem area={'gamesFound'}>
|
|
<Text>Games Found: {games.count.totalGames}</Text>
|
|
</GridItem>
|
|
<GridItem area={"forwardArrows"}>
|
|
<Flex justifySelf={'end'}>
|
|
<Tooltip content="Next Page">
|
|
<IconButton
|
|
aria-label={'Next Page'}
|
|
onMouseDown={nextPage}
|
|
disabled={pageIndex >= pageCount}
|
|
>
|
|
<LuChevronRight />
|
|
</IconButton>
|
|
</Tooltip>
|
|
<Tooltip content="Last Page">
|
|
<IconButton
|
|
aria-label={'Last Page'}
|
|
onMouseDown={() => gotoPage(pageCount)}
|
|
disabled={pageIndex >= pageCount}
|
|
ml={4}
|
|
>
|
|
<LuChevronsRight />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</Flex>
|
|
</GridItem>
|
|
</Grid>
|
|
)
|
|
}
|