From b5e717069756a2a778fc193bf6df76dfb75489f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 30 Dec 2025 20:23:06 -0600 Subject: [PATCH] feat: gun types --- .../TankSearch/components/FilterControl.tsx | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/packages/website/src/components/TankSearch/components/FilterControl.tsx b/packages/website/src/components/TankSearch/components/FilterControl.tsx index a05a0ef19..979cb2621 100644 --- a/packages/website/src/components/TankSearch/components/FilterControl.tsx +++ b/packages/website/src/components/TankSearch/components/FilterControl.tsx @@ -1,5 +1,6 @@ import { asset, + GunDefinition, ShellType, TANK_CLASSES, TIER_ROMAN_NUMERALS, @@ -7,10 +8,14 @@ import { import { TrashIcon } from "@radix-ui/react-icons"; import { Box, Button, DropdownMenu, Flex, Text } from "@radix-ui/themes"; import { times } from "lodash-es"; +import type { ComponentProps, ReactNode } from "react"; import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions"; import { useLocale } from "../../../hooks/useLocale"; -import { TankFilters } from "../../../stores/tankFilters"; +import { TankFilters, type CaseType } from "../../../stores/tankFilters"; import { classIcons } from "../../ClassIcon"; +import { GunAutoloaderIcon } from "../../GunAutoloaderIcon"; +import { GunAutoreloaderIcon } from "../../GunAutoreloaderIcon"; +import { GunRegularIcon } from "../../GunRegularIcon"; const gameDefinitions = await awaitableGameDefinitions; @@ -21,6 +26,19 @@ const shellTypeIcons: Record = { [ShellType.HEAT]: "hc", }; +const GUN_TYPE_ICONS: Record< + CaseType, + (props: ComponentProps<"svg">) => ReactNode +> = { + regular: GunRegularIcon, + auto_loader: GunAutoloaderIcon, + auto_reloader: GunAutoreloaderIcon, +}; + +const GUN_TYPES = Object.keys( + GUN_TYPE_ICONS +) as (keyof typeof GUN_TYPE_ICONS)[]; + const MAX_NATIONS = 3; const MAX_TIERS = 2; @@ -32,6 +50,7 @@ export function FilterControl() { + ); } @@ -295,3 +314,81 @@ function ClassFilter() { ); } + +function GunTypeFilter() { + const rawGunTypes = TankFilters.use((state) => state.gunType); + const gunTypes = rawGunTypes.length === 0 ? GUN_TYPES : rawGunTypes; + const { strings } = useLocale(); + + return ( + + + + + + + {GUN_TYPES.map((gunType) => { + const selected = rawGunTypes.includes(gunType); + const Icon = GUN_TYPE_ICONS[gunType]; + + return ( + { + event.preventDefault(); + + TankFilters.mutate((draft) => { + if (selected) { + draft.gunType = draft.gunType.filter((c) => c !== gunType); + } else { + draft.gunType = [...draft.gunType, gunType]; + } + }); + }} + checked={selected} + key={gunType} + > + + + {strings.common.gun_types[gunType]} + + ); + })} + + + + { + event.preventDefault(); + + TankFilters.mutate((draft) => { + draft.gunType = []; + }); + }} + > + + Clear + + + + ); +}