mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: rows per page
This commit is contained in:
1 parent
3ea77f5899
commit
322f95e42e
1 file changed
+34
-14
@@ -1,6 +1,10 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { MagnifyingGlassIcon } from '@radix-ui/react-icons';
|
import {
|
||||||
|
CaretLeftIcon,
|
||||||
|
CaretRightIcon,
|
||||||
|
MagnifyingGlassIcon,
|
||||||
|
} from '@radix-ui/react-icons';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Flex,
|
Flex,
|
||||||
@@ -26,7 +30,7 @@ import { getArchivedRatingsLeaderboardAPI } from '../../../core/blitzkrieg/getAr
|
|||||||
import { numberFetcher } from '../../../core/blitzkrieg/numberFetcher';
|
import { numberFetcher } from '../../../core/blitzkrieg/numberFetcher';
|
||||||
import { noArrows } from './page.css';
|
import { noArrows } from './page.css';
|
||||||
|
|
||||||
const ROWS_PER_PAGE = 64;
|
const ROWS_OPTIONS = [5, 10, 25, 50, 100];
|
||||||
|
|
||||||
const useUsernameCache = create<Record<Region, Record<number, string>>>(() => ({
|
const useUsernameCache = create<Record<Region, Record<number, string>>>(() => ({
|
||||||
asia: {},
|
asia: {},
|
||||||
@@ -42,6 +46,7 @@ const useClanCache = create<Record<Region, Record<number, string | undefined>>>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
const [rowsPerPage, setRowsPerPage] = useState(ROWS_OPTIONS[2]);
|
||||||
const usernameCache = useUsernameCache();
|
const usernameCache = useUsernameCache();
|
||||||
const clanCache = useClanCache();
|
const clanCache = useClanCache();
|
||||||
const [region, setRegion] = useState<Region>('com');
|
const [region, setRegion] = useState<Region>('com');
|
||||||
@@ -70,8 +75,8 @@ export default function Page() {
|
|||||||
const [page, setPage] = useState(0);
|
const [page, setPage] = useState(0);
|
||||||
const pageInput = useRef<HTMLInputElement>(null);
|
const pageInput = useRef<HTMLInputElement>(null);
|
||||||
const playerSlice = players.data?.slice(
|
const playerSlice = players.data?.slice(
|
||||||
page * ROWS_PER_PAGE,
|
page * rowsPerPage,
|
||||||
page * ROWS_PER_PAGE + ROWS_PER_PAGE,
|
page * rowsPerPage + rowsPerPage,
|
||||||
);
|
);
|
||||||
|
|
||||||
cachePage(page - 1);
|
cachePage(page - 1);
|
||||||
@@ -80,7 +85,7 @@ export default function Page() {
|
|||||||
|
|
||||||
function cachePage(page: number) {
|
function cachePage(page: number) {
|
||||||
const ids = players.data
|
const ids = players.data
|
||||||
?.slice(page * ROWS_PER_PAGE, page * ROWS_PER_PAGE + ROWS_PER_PAGE)
|
?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
.map(({ id }) => id)
|
.map(({ id }) => id)
|
||||||
.filter((id) => !(id in usernameCache[region]));
|
.filter((id) => !(id in usernameCache[region]));
|
||||||
|
|
||||||
@@ -234,14 +239,29 @@ export default function Page() {
|
|||||||
</Popover.Content>
|
</Popover.Content>
|
||||||
</Popover.Root>
|
</Popover.Root>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
|
<Select.Root
|
||||||
|
onValueChange={(value) => setRowsPerPage(parseInt(value))}
|
||||||
|
defaultValue={`${rowsPerPage}`}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
|
||||||
|
<Select.Content>
|
||||||
|
{ROWS_OPTIONS.map((size) => (
|
||||||
|
<Select.Item value={`${size}`} key={size}>
|
||||||
|
{size} per page
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
|
||||||
<Flex gap="2" align="center">
|
<Flex gap="2" align="center">
|
||||||
<Button
|
<Button
|
||||||
variant="soft"
|
variant="soft"
|
||||||
onClick={() => setPage((page) => Math.max(page - 1, 0))}
|
onClick={() => setPage((page) => Math.max(page - 1, 0))}
|
||||||
>
|
>
|
||||||
{'<'}
|
<CaretLeftIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<TextField.Root className={noArrows}>
|
<TextField.Root className={noArrows}>
|
||||||
<TextField.Slot>Page</TextField.Slot>
|
<TextField.Slot>Page</TextField.Slot>
|
||||||
<TextField.Input
|
<TextField.Input
|
||||||
@@ -254,7 +274,7 @@ export default function Page() {
|
|||||||
Math.max(
|
Math.max(
|
||||||
0,
|
0,
|
||||||
Math.min(
|
Math.min(
|
||||||
Math.floor((players.data?.length ?? 0) / ROWS_PER_PAGE),
|
Math.floor((players.data?.length ?? 0) / rowsPerPage),
|
||||||
event.target.valueAsNumber - 1,
|
event.target.valueAsNumber - 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -267,22 +287,21 @@ export default function Page() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextField.Slot>
|
<TextField.Slot>
|
||||||
out of {Math.ceil((players.data?.length ?? 0) / ROWS_PER_PAGE)}
|
out of {Math.ceil((players.data?.length ?? 0) / rowsPerPage)}
|
||||||
</TextField.Slot>
|
</TextField.Slot>
|
||||||
</TextField.Root>
|
</TextField.Root>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="soft"
|
variant="soft"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setPage((page) =>
|
setPage((page) =>
|
||||||
Math.min(
|
Math.min(
|
||||||
page + 1,
|
page + 1,
|
||||||
Math.floor((players.data?.length ?? 0) / ROWS_PER_PAGE),
|
Math.floor((players.data?.length ?? 0) / rowsPerPage),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{'>'}
|
<CaretRightIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -291,9 +310,10 @@ export default function Page() {
|
|||||||
{playerSlice?.map((player, index) => (
|
{playerSlice?.map((player, index) => (
|
||||||
<Leaderboard.Item
|
<Leaderboard.Item
|
||||||
nickname={
|
nickname={
|
||||||
usernameCache[region][player.id] ?? `Unknown player ${player.id}`
|
usernameCache[region][player.id] ??
|
||||||
|
`Loading player ${player.id}...`
|
||||||
}
|
}
|
||||||
position={page * ROWS_PER_PAGE + index + 1}
|
position={page * rowsPerPage + index + 1}
|
||||||
score={player.score}
|
score={player.score}
|
||||||
clan={clanCache[region][player.id]}
|
clan={clanCache[region][player.id]}
|
||||||
key={player.id}
|
key={player.id}
|
||||||
|
|||||||
Reference in new issue
Block a user