mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: compact nations selector
This commit is contained in:
1 parent
b6d6fa7212
commit
06ce263668
2 files changed
+98
-623
No files matched your search
@@ -759,11 +759,13 @@
|
|||||||
"count_singular": "1 tank",
|
"count_singular": "1 tank",
|
||||||
"count_plural": "{count} tanks",
|
"count_plural": "{count} tanks",
|
||||||
"sorting_by": "Sorting by {name}",
|
"sorting_by": "Sorting by {name}",
|
||||||
|
|
||||||
"no_tanks_found": {
|
"no_tanks_found": {
|
||||||
"body": "No tanks found.",
|
"body": "No tanks found.",
|
||||||
"search_again": "Try searching again.",
|
"search_again": "Try searching again.",
|
||||||
"clear_filters": "Try clearing filters."
|
"clear_filters": "Try clearing filters."
|
||||||
},
|
},
|
||||||
|
|
||||||
"sort": {
|
"sort": {
|
||||||
"meta.none": "none",
|
"meta.none": "none",
|
||||||
"survivability.health": "health",
|
"survivability.health": "health",
|
||||||
|
|||||||
@@ -1,42 +1,28 @@
|
|||||||
|
import { asset, ShellType } from "@blitzkit/core";
|
||||||
import {
|
import {
|
||||||
asset,
|
LockClosedIcon,
|
||||||
ShellType,
|
LockOpen2Icon,
|
||||||
TANK_CLASSES,
|
TrashIcon,
|
||||||
TankType,
|
} from "@radix-ui/react-icons";
|
||||||
TIER_ROMAN_NUMERALS,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { LockClosedIcon, LockOpen2Icon } from "@radix-ui/react-icons";
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
|
Button,
|
||||||
|
DropdownMenu,
|
||||||
Flex,
|
Flex,
|
||||||
IconButton,
|
IconButton,
|
||||||
Inset,
|
Inset,
|
||||||
Link,
|
|
||||||
Popover,
|
Popover,
|
||||||
Text,
|
Text,
|
||||||
Tooltip,
|
|
||||||
type ButtonProps,
|
|
||||||
type FlexProps,
|
type FlexProps,
|
||||||
} from "@radix-ui/themes";
|
} from "@radix-ui/themes";
|
||||||
import { isEqual, times, chunk } from "lodash-es";
|
import { isEqual } from "lodash-es";
|
||||||
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
|
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
|
||||||
import { awaitableConsumableDefinitions } from "../../../core/awaitables/consumableDefinitions";
|
|
||||||
import { Var } from "../../../core/radix/var";
|
|
||||||
import { useLocale } from "../../../hooks/useLocale";
|
import { useLocale } from "../../../hooks/useLocale";
|
||||||
import { App } from "../../../stores/app";
|
import { App } from "../../../stores/app";
|
||||||
import { TankFilters } from "../../../stores/tankFilters";
|
import { TankFilters } from "../../../stores/tankFilters";
|
||||||
import { TankSort } from "../../../stores/tankopediaSort";
|
|
||||||
import { classIcons } from "../../ClassIcon";
|
|
||||||
import { GunAutoloaderIcon } from "../../GunAutoloaderIcon";
|
|
||||||
import { GunAutoreloaderIcon } from "../../GunAutoreloaderIcon";
|
|
||||||
import { GunRegularIcon } from "../../GunRegularIcon";
|
|
||||||
import { MissingShellIcon } from "../../MissingShellIcon";
|
import { MissingShellIcon } from "../../MissingShellIcon";
|
||||||
import { ResearchedIcon } from "../../ResearchedIcon";
|
|
||||||
import { ScienceIcon } from "../../ScienceIcon";
|
|
||||||
import { ScienceOffIcon } from "../../ScienceOffIcon";
|
|
||||||
|
|
||||||
const gameDefinitions = await awaitableGameDefinitions;
|
const gameDefinitions = await awaitableGameDefinitions;
|
||||||
const consumableDefinitions = await awaitableConsumableDefinitions;
|
|
||||||
|
|
||||||
const shellTypeIcons: Record<ShellType, string> = {
|
const shellTypeIcons: Record<ShellType, string> = {
|
||||||
[ShellType.AP]: "ap",
|
[ShellType.AP]: "ap",
|
||||||
@@ -45,26 +31,7 @@ const shellTypeIcons: Record<ShellType, string> = {
|
|||||||
[ShellType.HEAT]: "hc",
|
[ShellType.HEAT]: "hc",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get consumables
|
const MAX_NATIONS = 3;
|
||||||
const regularConsumables = Object.values(
|
|
||||||
consumableDefinitions.consumables
|
|
||||||
).filter(
|
|
||||||
(consumable) =>
|
|
||||||
!consumable.game_mode_exclusive && consumable.name.locales.en !== ""
|
|
||||||
);
|
|
||||||
|
|
||||||
// Split consumables into chunks of 5 for columns
|
|
||||||
const consumableColumns = chunk(regularConsumables, 5);
|
|
||||||
|
|
||||||
// Get game mode exclusive abilities
|
|
||||||
const gameModeAbilities = Object.values(
|
|
||||||
consumableDefinitions.consumables
|
|
||||||
).filter((consumable) => consumable.game_mode_exclusive);
|
|
||||||
|
|
||||||
// Split abilities into chunks of 5 for columns
|
|
||||||
const abilityColumns = chunk(gameModeAbilities, 5);
|
|
||||||
|
|
||||||
const size: ButtonProps["size"] = { initial: "1", xs: "2" };
|
|
||||||
|
|
||||||
function ShellFilter({ index, premium }: { index: number; premium?: boolean }) {
|
function ShellFilter({ index, premium }: { index: number; premium?: boolean }) {
|
||||||
const shells = TankFilters.use((state) => state.shells);
|
const shells = TankFilters.use((state) => state.shells);
|
||||||
@@ -72,13 +39,7 @@ function ShellFilter({ index, premium }: { index: number; premium?: boolean }) {
|
|||||||
return (
|
return (
|
||||||
<Popover.Root>
|
<Popover.Root>
|
||||||
<Popover.Trigger>
|
<Popover.Trigger>
|
||||||
<IconButton
|
<IconButton variant="soft" radius="none" color="gray" highContrast>
|
||||||
size={size}
|
|
||||||
variant="soft"
|
|
||||||
radius="none"
|
|
||||||
color="gray"
|
|
||||||
highContrast
|
|
||||||
>
|
|
||||||
{shells[index] === null && (
|
{shells[index] === null && (
|
||||||
<Text color="gray" style={{ display: "contents" }}>
|
<Text color="gray" style={{ display: "contents" }}>
|
||||||
<MissingShellIcon width="1em" height="1em" />
|
<MissingShellIcon width="1em" height="1em" />
|
||||||
@@ -107,7 +68,6 @@ function ShellFilter({ index, premium }: { index: number; premium?: boolean }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
size={size}
|
|
||||||
key={shellType}
|
key={shellType}
|
||||||
value={`${shellType}`}
|
value={`${shellType}`}
|
||||||
radius="none"
|
radius="none"
|
||||||
@@ -154,7 +114,6 @@ function OwnershipFilter(props: FlexProps) {
|
|||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
size={size}
|
|
||||||
disabled={!wargaming}
|
disabled={!wargaming}
|
||||||
variant={tankFilters.showOwned ? "solid" : "soft"}
|
variant={tankFilters.showOwned ? "solid" : "soft"}
|
||||||
radius="none"
|
radius="none"
|
||||||
@@ -170,7 +129,6 @@ function OwnershipFilter(props: FlexProps) {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
size={size}
|
|
||||||
disabled={!wargaming}
|
disabled={!wargaming}
|
||||||
variant={tankFilters.showUnowned ? "solid" : "soft"}
|
variant={tankFilters.showUnowned ? "solid" : "soft"}
|
||||||
radius="none"
|
radius="none"
|
||||||
@@ -194,598 +152,113 @@ export function FilterControl() {
|
|||||||
const clearable = !isEqual(tankFilters, TankFilters.initial);
|
const clearable = !isEqual(tankFilters, TankFilters.initial);
|
||||||
const wargaming = App.use((state) => state.logins.wargaming);
|
const wargaming = App.use((state) => state.logins.wargaming);
|
||||||
|
|
||||||
|
const nations =
|
||||||
|
tankFilters.nations.length === 0
|
||||||
|
? gameDefinitions.nations
|
||||||
|
: tankFilters.nations;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" align="center">
|
<Flex align="center" gap="2">
|
||||||
<Flex height="fit-content" gap="1" align="start" justify="center">
|
<DropdownMenu.Root>
|
||||||
<Flex
|
<DropdownMenu.Trigger>
|
||||||
flexShrink="0"
|
<Button color="gray" variant="surface">
|
||||||
overflow="hidden"
|
Nations
|
||||||
style={{ borderRadius: "var(--radius-4)" }}
|
<Flex>
|
||||||
>
|
{nations.slice(0, MAX_NATIONS).map((nation, index) => (
|
||||||
<Flex direction="column">
|
<img
|
||||||
{times(5, (index) => {
|
style={{
|
||||||
const tier = index + 1;
|
marginLeft: index > 0 ? "-0.5em" : undefined,
|
||||||
const selected = tankFilters.tiers?.includes(tier);
|
width: "1.25em",
|
||||||
|
height: "1.25em",
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={tier}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
radius="none"
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
if (tankFilters.tiers.includes(tier)) {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
draft.tiers = draft.tiers.filter((t) => t !== tier);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
draft.tiers = [...draft.tiers, tier];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
src={asset(`flags/circle/${nation}.webp`)}
|
||||||
<Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text>
|
/>
|
||||||
</IconButton>
|
))}
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Box
|
{nations.length > MAX_NATIONS && (
|
||||||
display={{ initial: "none", md: "block" }}
|
<Text size="1" ml="1">
|
||||||
style={{
|
+{nations.length - MAX_NATIONS}
|
||||||
height: Var("space-1"),
|
</Text>
|
||||||
backgroundColor: Var("gray-a3"),
|
)}
|
||||||
}}
|
</Flex>
|
||||||
/>
|
</Button>
|
||||||
|
</DropdownMenu.Trigger>
|
||||||
|
|
||||||
<Flex direction="column">
|
<DropdownMenu.Content>
|
||||||
{times(5, (index) => {
|
{gameDefinitions.nations.map((nation) => {
|
||||||
const tier = index + 6;
|
const selected = tankFilters.nations.includes(nation);
|
||||||
const selected = tankFilters.tiers?.includes(tier);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={tier}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
radius="none"
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
if (tankFilters.tiers.includes(tier)) {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
draft.tiers = draft.tiers.filter((t) => t !== tier);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
draft.tiers = [...draft.tiers, tier];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex
|
|
||||||
flexShrink="0"
|
|
||||||
overflow="hidden"
|
|
||||||
style={{ borderRadius: "var(--radius-4)" }}
|
|
||||||
>
|
|
||||||
<Flex direction="column">
|
|
||||||
{gameDefinitions.nations
|
|
||||||
.slice(0, Math.ceil(gameDefinitions.nations.length / 2))
|
|
||||||
.map((nation) => {
|
|
||||||
const selected = tankFilters.nations?.includes(nation);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={nation}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
radius="none"
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.nations.includes(nation)) {
|
|
||||||
draft.nations = draft.nations.filter(
|
|
||||||
(n) => n !== nation
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.nations = [...draft.nations, nation];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style={{ width: "1em", height: "1em" }}
|
|
||||||
src={asset(`flags/circle/${nation}.webp`)}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Box
|
|
||||||
display={{ initial: "none", md: "block" }}
|
|
||||||
style={{
|
|
||||||
height: Var("space-1"),
|
|
||||||
backgroundColor: Var("gray-a3"),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Flex direction="column">
|
|
||||||
{gameDefinitions.nations
|
|
||||||
.slice(Math.ceil(gameDefinitions.nations.length / 2))
|
|
||||||
.map((nation) => {
|
|
||||||
const selected = tankFilters.nations?.includes(nation);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={nation}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
radius="none"
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.nations.includes(nation)) {
|
|
||||||
draft.nations = draft.nations.filter(
|
|
||||||
(n) => n !== nation
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.nations = [...draft.nations, nation];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style={{ width: "1em", height: "1em" }}
|
|
||||||
src={asset(`flags/circle/${nation}.webp`)}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{/* Consumables Filter - RIGHT AFTER NATIONS */}
|
|
||||||
<Flex
|
|
||||||
flexShrink="0"
|
|
||||||
overflow="hidden"
|
|
||||||
style={{ borderRadius: "var(--radius-4)" }}
|
|
||||||
>
|
|
||||||
<Flex direction="column">
|
|
||||||
{consumableColumns[0]?.map((consumable) => {
|
|
||||||
const selected = tankFilters.consumables?.includes(consumable.id);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={consumable.id}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
radius="none"
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.consumables.includes(consumable.id)) {
|
|
||||||
draft.consumables = draft.consumables.filter(
|
|
||||||
(c) => c !== consumable.id
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.consumables = [
|
|
||||||
...draft.consumables,
|
|
||||||
consumable.id,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style={{ width: "1em", height: "1em" }}
|
|
||||||
src={asset(`icons/consumables/${consumable.id}.webp`)}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{consumableColumns[1] && (
|
|
||||||
<>
|
|
||||||
<Box
|
|
||||||
display={{ initial: "none", md: "block" }}
|
|
||||||
style={{
|
|
||||||
height: Var("space-1"),
|
|
||||||
backgroundColor: Var("gray-a3"),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Flex direction="column">
|
|
||||||
{consumableColumns[1].map((consumable) => {
|
|
||||||
const selected = tankFilters.consumables?.includes(
|
|
||||||
consumable.id
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={consumable.id}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
radius="none"
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.consumables.includes(consumable.id)) {
|
|
||||||
draft.consumables = draft.consumables.filter(
|
|
||||||
(c) => c !== consumable.id
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.consumables = [
|
|
||||||
...draft.consumables,
|
|
||||||
consumable.id,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style={{ width: "1em", height: "1em" }}
|
|
||||||
src={asset(`icons/consumables/${consumable.id}.webp`)}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{consumableColumns[2] && (
|
|
||||||
<>
|
|
||||||
<Box
|
|
||||||
display={{ initial: "none", md: "block" }}
|
|
||||||
style={{
|
|
||||||
height: Var("space-1"),
|
|
||||||
backgroundColor: Var("gray-a3"),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Flex direction="column">
|
|
||||||
{consumableColumns[2].map((consumable) => {
|
|
||||||
const selected = tankFilters.consumables?.includes(
|
|
||||||
consumable.id
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
key={consumable.id}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
radius="none"
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.consumables.includes(consumable.id)) {
|
|
||||||
draft.consumables = draft.consumables.filter(
|
|
||||||
(c) => c !== consumable.id
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.consumables = [
|
|
||||||
...draft.consumables,
|
|
||||||
consumable.id,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style={{ width: "1em", height: "1em" }}
|
|
||||||
src={asset(`icons/consumables/${consumable.id}.webp`)}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex
|
|
||||||
overflow="hidden"
|
|
||||||
style={{ borderRadius: "var(--radius-full)" }}
|
|
||||||
direction="column"
|
|
||||||
>
|
|
||||||
{TANK_CLASSES.map((tankClass) => {
|
|
||||||
const Icon = classIcons[tankClass];
|
|
||||||
const selected = tankFilters.classes?.includes(tankClass);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<DropdownMenu.CheckboxItem
|
||||||
size={size}
|
onClick={(event) => {
|
||||||
key={tankClass}
|
event.preventDefault();
|
||||||
variant={selected ? "solid" : "soft"}
|
|
||||||
radius="none"
|
|
||||||
color={selected ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
TankFilters.mutate((draft) => {
|
||||||
if (tankFilters.classes.includes(tankClass)) {
|
if (selected) {
|
||||||
draft.classes = draft.classes.filter(
|
draft.nations = draft.nations.filter((n) => n !== nation);
|
||||||
(c) => c !== tankClass
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
draft.classes = [...draft.classes, tankClass];
|
draft.nations = [...draft.nations, nation];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
checked={selected}
|
||||||
|
key={nation}
|
||||||
|
style={{
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Icon style={{ width: "1em", height: "1em" }} />
|
<Box
|
||||||
</IconButton>
|
width="calc(100% + calc(4 * var(--space-2)))"
|
||||||
|
height="100%"
|
||||||
|
position="absolute"
|
||||||
|
right="0"
|
||||||
|
mr="-2"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${asset(
|
||||||
|
`flags/scratched/${nation}.webp`
|
||||||
|
)})`,
|
||||||
|
backgroundSize: "100%",
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundPosition: "5rem center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(90deg, var(--gray-2) 50%, transparent)`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Text style={{ zIndex: 1 }}>
|
||||||
|
{
|
||||||
|
strings.common.nations[
|
||||||
|
nation as keyof typeof strings.common.nations
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</Text>
|
||||||
|
</DropdownMenu.CheckboxItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex
|
<DropdownMenu.Separator />
|
||||||
overflow="hidden"
|
|
||||||
style={{ borderRadius: "var(--radius-full)" }}
|
|
||||||
direction="column"
|
|
||||||
>
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={tankFilters.gunType.includes("regular") ? "solid" : "soft"}
|
|
||||||
radius="none"
|
|
||||||
color={tankFilters.gunType.includes("regular") ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.gunType.includes("regular")) {
|
|
||||||
draft.gunType = draft.gunType.filter((t) => t !== "regular");
|
|
||||||
} else {
|
|
||||||
draft.gunType = [...draft.gunType, "regular"];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<GunRegularIcon style={{ width: "1em", height: "1em" }} />
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={
|
|
||||||
tankFilters.gunType.includes("auto_loader") ? "solid" : "soft"
|
|
||||||
}
|
|
||||||
radius="none"
|
|
||||||
color={
|
|
||||||
tankFilters.gunType.includes("auto_loader") ? undefined : "gray"
|
|
||||||
}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.gunType.includes("auto_loader")) {
|
|
||||||
draft.gunType = draft.gunType.filter(
|
|
||||||
(t) => t !== "auto_loader"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.gunType = [...draft.gunType, "auto_loader"];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<GunAutoloaderIcon style={{ width: "1em", height: "1em" }} />
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={
|
|
||||||
tankFilters.gunType.includes("auto_reloader") ? "solid" : "soft"
|
|
||||||
}
|
|
||||||
radius="none"
|
|
||||||
color={
|
|
||||||
tankFilters.gunType.includes("auto_reloader") ? undefined : "gray"
|
|
||||||
}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.gunType.includes("auto_reloader")) {
|
|
||||||
draft.gunType = draft.gunType.filter(
|
|
||||||
(t) => t !== "auto_reloader"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.gunType = [...draft.gunType, "auto_reloader"];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<GunAutoreloaderIcon style={{ width: "1em", height: "1em" }} />
|
|
||||||
</IconButton>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex
|
<DropdownMenu.Item
|
||||||
overflow="hidden"
|
color="red"
|
||||||
style={{ borderRadius: "var(--radius-full)" }}
|
onClick={(event) => {
|
||||||
direction="column"
|
event.preventDefault();
|
||||||
>
|
|
||||||
<ShellFilter index={0} />
|
|
||||||
<ShellFilter index={1} premium />
|
|
||||||
<ShellFilter index={2} />
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex
|
|
||||||
overflow="hidden"
|
|
||||||
style={{ borderRadius: "var(--radius-full)" }}
|
|
||||||
direction="column"
|
|
||||||
>
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={
|
|
||||||
tankFilters.types?.includes(TankType.RESEARCHABLE)
|
|
||||||
? "solid"
|
|
||||||
: "soft"
|
|
||||||
}
|
|
||||||
radius="none"
|
|
||||||
color={
|
|
||||||
tankFilters.types?.includes(TankType.RESEARCHABLE)
|
|
||||||
? undefined
|
|
||||||
: "gray"
|
|
||||||
}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
TankFilters.mutate((draft) => {
|
||||||
if (tankFilters.types.includes(TankType.RESEARCHABLE)) {
|
draft.nations = [];
|
||||||
draft.types = draft.types.filter(
|
|
||||||
(t) => t !== TankType.RESEARCHABLE
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.types = [...draft.types, TankType.RESEARCHABLE];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ResearchedIcon style={{ width: "1em", height: "1em" }} />
|
<TrashIcon />
|
||||||
</IconButton>
|
Clear
|
||||||
<IconButton
|
</DropdownMenu.Item>
|
||||||
size={size}
|
</DropdownMenu.Content>
|
||||||
variant={
|
</DropdownMenu.Root>
|
||||||
tankFilters.types?.includes(TankType.PREMIUM) ? "solid" : "soft"
|
|
||||||
}
|
|
||||||
radius="none"
|
|
||||||
color={
|
|
||||||
tankFilters.types?.includes(TankType.PREMIUM) ? "amber" : "gray"
|
|
||||||
}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.types.includes(TankType.PREMIUM)) {
|
|
||||||
draft.types = draft.types.filter(
|
|
||||||
(t) => t !== TankType.PREMIUM
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.types = [...draft.types, TankType.PREMIUM];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
color={
|
|
||||||
tankFilters.types?.includes(TankType.PREMIUM)
|
|
||||||
? undefined
|
|
||||||
: "amber"
|
|
||||||
}
|
|
||||||
style={{ display: "flex", justifyContent: "center" }}
|
|
||||||
>
|
|
||||||
<ResearchedIcon style={{ width: "1em", height: "1em" }} />
|
|
||||||
</Text>
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={
|
|
||||||
tankFilters.types?.includes(TankType.COLLECTOR) ? "solid" : "soft"
|
|
||||||
}
|
|
||||||
radius="none"
|
|
||||||
color={
|
|
||||||
tankFilters.types?.includes(TankType.COLLECTOR) ? "blue" : "gray"
|
|
||||||
}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
if (tankFilters.types.includes(TankType.COLLECTOR)) {
|
|
||||||
draft.types = draft.types.filter(
|
|
||||||
(t) => t !== TankType.COLLECTOR
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.types = [...draft.types, TankType.COLLECTOR];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
color={
|
|
||||||
tankFilters.types?.includes(TankType.COLLECTOR)
|
|
||||||
? undefined
|
|
||||||
: "blue"
|
|
||||||
}
|
|
||||||
style={{ display: "flex", justifyContent: "center" }}
|
|
||||||
>
|
|
||||||
<ResearchedIcon style={{ width: "1em", height: "1em" }} />
|
|
||||||
</Text>
|
|
||||||
</IconButton>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex
|
|
||||||
overflow="hidden"
|
|
||||||
style={{ borderRadius: "var(--radius-full)" }}
|
|
||||||
direction="column"
|
|
||||||
>
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={tankFilters.showNonTesting ? "solid" : "soft"}
|
|
||||||
radius="none"
|
|
||||||
color={tankFilters.showNonTesting ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
draft.showNonTesting = !draft.showNonTesting;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ScienceOffIcon
|
|
||||||
style={{ width: "1em", height: "1em", color: "currentColor" }}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
size={size}
|
|
||||||
variant={tankFilters.showTesting ? "solid" : "soft"}
|
|
||||||
radius="none"
|
|
||||||
color={tankFilters.showTesting ? undefined : "gray"}
|
|
||||||
highContrast
|
|
||||||
onClick={() => {
|
|
||||||
TankFilters.mutate((draft) => {
|
|
||||||
draft.showTesting = !draft.showTesting;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ScienceIcon
|
|
||||||
style={{ width: "1em", height: "1em", color: "currentColor" }}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{wargaming ? (
|
|
||||||
<OwnershipFilter />
|
|
||||||
) : (
|
|
||||||
<Tooltip content={strings.website.common.tank_search.login}>
|
|
||||||
<OwnershipFilter />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{clearable && (
|
|
||||||
<Link
|
|
||||||
color="red"
|
|
||||||
underline="always"
|
|
||||||
mt="4"
|
|
||||||
href="#"
|
|
||||||
onClick={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
TankFilters.set(TankFilters.initial);
|
|
||||||
TankSort.set(TankSort.initial);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{strings.website.common.tank_search.clear_filters}
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user