'use client'; import { slateDark } from '@radix-ui/colors'; import { CaretDownIcon, CaretUpIcon, MagnifyingGlassIcon, } from '@radix-ui/react-icons'; import { Button, Card, DropdownMenu, Flex, Inset, Text, TextField, } from '@radix-ui/themes'; import { go } from 'fuzzysort'; import Link from 'next/link'; import { Suspense, use, useEffect, useMemo, useRef, useState } from 'react'; import PageWrapper from '../../../components/PageWrapper'; import { asset } from '../../../core/blitzkrieg/asset'; import { TANK_ICONS, TANK_ICONS_COLLECTOR, TANK_ICONS_PREMIUM, TIER_ROMAN_NUMERALS, TankDefinition, tanksDefinitionsArray, } from '../../../core/blitzkrieg/tankDefinitions'; import { tankIcon } from '../../../core/blitzkrieg/tankIcon'; import { theme } from '../../../stitches.config'; import mutateTankopedia, { TankopediaSortBy, TankopediaSortDirection, useTankopedia, } from '../../../stores/tankopedia'; import { Options } from './components/Options'; import { PageTurner } from './components/PageTurner'; import * as styles from './page.css'; const TANKS_PER_PAGE = 3 * 2 ** 3; export default function Page() { const tankopediaState = useTankopedia(); const awaitedTanks = use(tanksDefinitionsArray); const input = useRef(null); const searchableTanks = useMemo( () => awaitedTanks .filter( (tank) => (tankopediaState.filters.tiers.length === 0 ? true : tankopediaState.filters.tiers.includes(tank.tier)) && (tankopediaState.filters.types.length === 0 ? true : tankopediaState.filters.types.includes(tank.type)) && (tankopediaState.filters.treeTypes.length === 0 ? true : tankopediaState.filters.treeTypes.includes(tank.tree_type)) && (tankopediaState.filters.nations.length === 0 ? true : tankopediaState.filters.nations.includes(tank.nation)) && (tankopediaState.filters.test === 'include' ? true : tankopediaState.filters.test === 'exclude' ? !tank.testing : tank.testing), ) .sort((a, b) => { let diff = 0; if (tankopediaState.sort.by === 'tier') { diff = a.tier - b.tier; } if (tankopediaState.sort.by === 'name') { diff = a.name.localeCompare(b.name); } return tankopediaState.sort.direction === 'ascending' ? diff : -diff; }), [tankopediaState.filters, tankopediaState.sort], ); const [searchedList, setSearchedList] = useState(searchableTanks); const [page, setPage] = useState(0); const [showFilters, setShowFilters] = useState(false); useEffect(() => { setSearchedList(searchableTanks); if (input.current) input.current.value = ''; }, [searchableTanks]); useEffect(() => { setPage( Math.min( Math.max(0, page), Math.ceil(searchedList.length / TANKS_PER_PAGE) - 1, ), ); }, [searchedList]); return ( Loading...}> { if (event.target.value.length === 0) { setSearchedList(searchableTanks); } else { setSearchedList( go(event.target.value, searchableTanks, { keys: ['name', 'id'] satisfies (keyof TankDefinition)[], }).map(({ obj }) => obj), ); } }} /> By mutateTankopedia((draft) => { draft.sort.by = value as TankopediaSortBy; }) } > Tier Name Direction mutateTankopedia((draft) => { draft.sort.direction = value as TankopediaSortDirection; }) } > Ascending Descending {showFilters && ( Loading...}> )} {searchedList .map((tank) => (
{tank.name} {TIER_ROMAN_NUMERALS[tank.tier]} )) .slice(page * TANKS_PER_PAGE, (page + 1) * TANKS_PER_PAGE)} ); }