diff --git a/src/app/tools/tank-performance/components/Header.tsx b/src/app/tools/tank-performance/components/Header.tsx index 44a77b328..fd2aade88 100644 --- a/src/app/tools/tank-performance/components/Header.tsx +++ b/src/app/tools/tank-performance/components/Header.tsx @@ -6,14 +6,15 @@ import { CaretUpIcon, } from '@radix-ui/react-icons'; import { Flex, IconButton, Table } from '@radix-ui/themes'; +import * as TankPerformanceSort from '../../../../stores/tankPerformanceSort'; import { tankPerformanceSortTypeNames, tankPerformanceSortTypeNamesArray, - useTankPerformanceSort, -} from '../../../../stores/tankPerformanceSort'; +} from '../../../../stores/tankPerformanceSort/constants'; export function Header() { - const sort = useTankPerformanceSort(); + const sort = TankPerformanceSort.use(); + const store = TankPerformanceSort.useStore(); return ( @@ -40,11 +41,9 @@ export function Header() { highContrast={!isSelected} onClick={() => { if (isSelected) { - useTankPerformanceSort.setState({ - direction: -sort.direction as 1 | -1, - }); + store.setState({ direction: -sort.direction as 1 | -1 }); } else { - useTankPerformanceSort.setState({ type, direction: -1 }); + store.setState({ type, direction: -1 }); } }} > diff --git a/src/app/tools/tank-performance/components/Info.tsx b/src/app/tools/tank-performance/components/Info.tsx index 6aa6c82f0..2e9859c25 100644 --- a/src/app/tools/tank-performance/components/Info.tsx +++ b/src/app/tools/tank-performance/components/Info.tsx @@ -20,7 +20,7 @@ export function Info() { Career stats based on {numberFormat.format(Math.round(samples))}{' '} - players with at least 5K career battles and 1 battle in the past 30 + players with at least 5K career battles and 1 battle in the past 120 days; updated daily. diff --git a/src/app/tools/tank-performance/components/RowLoader.tsx b/src/app/tools/tank-performance/components/RowLoader.tsx index 418e93d52..bf0b9ad6e 100644 --- a/src/app/tools/tank-performance/components/RowLoader.tsx +++ b/src/app/tools/tank-performance/components/RowLoader.tsx @@ -2,7 +2,7 @@ import { Skeleton, Table } from '@radix-ui/themes'; import { times } from 'lodash'; import { memo, useRef } from 'react'; import { useIntersection } from '../../../../hooks/useIntersection'; -import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort'; +import { tankPerformanceSortTypeNamesArray } from '../../../../stores/tankPerformanceSort/constants'; interface RowLoaderProps { onIntersection?: () => void; diff --git a/src/app/tools/tank-performance/components/Tanks.tsx b/src/app/tools/tank-performance/components/Tanks.tsx index 25af192a6..62172989c 100644 --- a/src/app/tools/tank-performance/components/Tanks.tsx +++ b/src/app/tools/tank-performance/components/Tanks.tsx @@ -7,7 +7,7 @@ import { averageDefinitionsArray } from '../../../../core/blitzkit/averageDefini import { filterTank } from '../../../../core/blitzkit/filterTank'; import { tankDefinitions } from '../../../../core/blitzkit/tankDefinitions'; import * as TankFilters from '../../../../stores/tankFilters'; -import { useTankPerformanceSort } from '../../../../stores/tankPerformanceSort'; +import * as TankPerformanceSort from '../../../../stores/tankPerformanceSort'; import { RowLoader } from './RowLoader'; import { TankRow } from './TankRow'; import { Total } from './Total'; @@ -19,7 +19,7 @@ export function Tanks() { const awaitedTankDefinitions = use(tankDefinitions); const awaitedAverageDefinitionsArray = use(averageDefinitionsArray); const filters = TankFilters.use(); - const sort = useTankPerformanceSort(); + const sort = TankPerformanceSort.use(); const tanksSorted = useMemo(() => { switch (sort.type) { case 'accuracy': @@ -126,6 +126,9 @@ export function Tanks() { {tanks.slice(0, loadedRows).map((averages) => { const tank = awaitedTankDefinitions[averages.id]; + + if (tank === undefined) return null; + return ( }> diff --git a/src/app/tools/tank-performance/components/TierBreakdown.tsx b/src/app/tools/tank-performance/components/TierBreakdown.tsx index ae851c26a..f4b9fcd34 100644 --- a/src/app/tools/tank-performance/components/TierBreakdown.tsx +++ b/src/app/tools/tank-performance/components/TierBreakdown.tsx @@ -33,7 +33,7 @@ export function TierBreakdown() { data={times(10, (index) => { const tier = (index + 1) as Tier; const tierTanks = awaitedAverageDefinitionsArray.filter( - ({ id }) => awaitedTankDefinitions[id].tier === tier, + ({ id }) => awaitedTankDefinitions[id]?.tier === tier, ); const populations: Record = { 'AT-SPG': 0, diff --git a/src/app/tools/tank-performance/layout.tsx b/src/app/tools/tank-performance/layout.tsx new file mode 100644 index 000000000..8a0c5b6b2 --- /dev/null +++ b/src/app/tools/tank-performance/layout.tsx @@ -0,0 +1,11 @@ +import { ReactNode } from 'react'; +import * as TankFilters from '../../../stores/tankFilters'; +import * as TankPerformanceSort from '../../../stores/tankPerformanceSort'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/src/app/tools/tank-performance/page.tsx b/src/app/tools/tank-performance/page.tsx index 1e4f6fdcc..4bb880d81 100644 --- a/src/app/tools/tank-performance/page.tsx +++ b/src/app/tools/tank-performance/page.tsx @@ -1,5 +1,4 @@ import PageWrapper from '../../../components/PageWrapper'; -import * as TankFilters from '../../../stores/tankFilters'; import { FilterControl } from '../tankopedia/components/FilterControl'; import { Info } from './components/Info'; import { TankTable } from './components/Table'; @@ -7,13 +6,11 @@ import { TierBreakdown } from './components/TierBreakdown'; export default function Page() { return ( - - - - - - - - + + + + + + ); } diff --git a/src/core/blitzkit/filterTank.ts b/src/core/blitzkit/filterTank.ts index 5351b09ee..e25e36fd1 100644 --- a/src/core/blitzkit/filterTank.ts +++ b/src/core/blitzkit/filterTank.ts @@ -1,3 +1,4 @@ +import { TankFilters } from '../../stores/tankFilters'; import { TankDefinition } from './tankDefinitions'; export function filterTank(filters: TankFilters, tank: TankDefinition) { diff --git a/src/core/zustand/createNextSafeStore.tsx b/src/core/zustand/createNextSafeStore.tsx index ec871f1d2..0fb75f015 100644 --- a/src/core/zustand/createNextSafeStore.tsx +++ b/src/core/zustand/createNextSafeStore.tsx @@ -42,9 +42,9 @@ export function createNextSafeStore(initialState: Type) { function useStore() { const store = useContext(Context); - if (!store) { - throw new Error('useStoreContext must be used within Provider'); - } + + if (!store) throw new Error('useStore must be used within Provider'); + return store; } diff --git a/src/stores/tankFilters.tsx b/src/stores/tankFilters.ts similarity index 100% rename from src/stores/tankFilters.tsx rename to src/stores/tankFilters.ts diff --git a/src/stores/tankPerformanceSort.ts b/src/stores/tankPerformanceSort.ts deleted file mode 100644 index 28b245245..000000000 --- a/src/stores/tankPerformanceSort.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { produce } from 'immer'; -import { create } from 'zustand'; - -export const tankPerformanceSortTypeNames = { - winrate: 'Winrate', - players: 'Players (30d)', - battles: 'Battles (career)', - damage: 'Damage', - survival: 'Survival', - xp: 'XP', - kills: 'Kills', - spots: 'Spots', - accuracy: 'Accuracy', - shots: 'Shots', - hits: 'Hits', - damageRatio: 'Dmg. ratio', - damageTaken: 'Dmg. taken', - capturePoints: 'Cap points', -} as const; - -export const tankPerformanceSortTypeNamesArray = Object.keys( - tankPerformanceSortTypeNames, -) as TankPerformanceSortType[]; - -type TankPerformanceSortType = keyof typeof tankPerformanceSortTypeNames; - -export interface TankPerformanceSort { - type: TankPerformanceSortType; - direction: -1 | 1; -} - -export const useTankPerformanceSort = create()(() => ({ - type: 'winrate', - direction: -1, -})); - -export function mutateTankPerformanceSort( - recipe: (draft: TankPerformanceSort) => void, -) { - useTankPerformanceSort.setState(produce(recipe)); -} diff --git a/src/stores/tankPerformanceSort/constants.ts b/src/stores/tankPerformanceSort/constants.ts new file mode 100644 index 000000000..461fd4a5c --- /dev/null +++ b/src/stores/tankPerformanceSort/constants.ts @@ -0,0 +1,21 @@ +import { TankPerformanceSortType } from '.'; + +export const tankPerformanceSortTypeNames = { + winrate: 'Winrate', + players: 'Players (30d)', + battles: 'Battles (career)', + damage: 'Damage', + survival: 'Survival', + xp: 'XP', + kills: 'Kills', + spots: 'Spots', + accuracy: 'Accuracy', + shots: 'Shots', + hits: 'Hits', + damageRatio: 'Dmg. ratio', + damageTaken: 'Dmg. taken', + capturePoints: 'Cap points', +} as const; +export const tankPerformanceSortTypeNamesArray = Object.keys( + tankPerformanceSortTypeNames, +) as TankPerformanceSortType[]; diff --git a/src/stores/tankPerformanceSort/index.ts b/src/stores/tankPerformanceSort/index.ts new file mode 100644 index 000000000..717815e57 --- /dev/null +++ b/src/stores/tankPerformanceSort/index.ts @@ -0,0 +1,17 @@ +'use client'; + +import { createNextSafeStore } from '../../core/zustand/createNextSafeStore'; +import { tankPerformanceSortTypeNames } from './constants'; + +export type TankPerformanceSortType = keyof typeof tankPerformanceSortTypeNames; + +export interface TankPerformanceSort { + type: TankPerformanceSortType; + direction: -1 | 1; +} + +export const { Provider, use, useMutation, useStore } = + createNextSafeStore({ + type: 'winrate', + direction: -1, + });