diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json
index 94def8954..9d077301b 100644
--- a/packages/i18n/strings/en.json
+++ b/packages/i18n/strings/en.json
@@ -762,6 +762,8 @@
"sorting_by": "Sorting by {name}",
"clear": "Clear",
"tier": "Tier {tier}",
+ "passive": "{name} (Passive)",
+ "active": "{name} (Active)",
"no_tanks_found": {
"body": "No tanks found.",
diff --git a/packages/website/src/components/TankSearch/components/FilterControl.tsx b/packages/website/src/components/TankSearch/components/FilterControl.tsx
index 139ff56f0..3991366a1 100644
--- a/packages/website/src/components/TankSearch/components/FilterControl.tsx
+++ b/packages/website/src/components/TankSearch/components/FilterControl.tsx
@@ -26,7 +26,7 @@ import {
type FlexProps,
} from "@radix-ui/themes";
import { times } from "lodash-es";
-import { Fragment, useState, type ComponentProps, type ReactNode } from "react";
+import { Fragment, type ComponentProps, type ReactNode } from "react";
import { awaitableConsumableDefinitions } from "../../../core/awaitables/consumableDefinitions";
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
import { awaitableProvisionDefinitions } from "../../../core/awaitables/provisionDefinitions";
@@ -160,13 +160,16 @@ export function FilterControl() {
+
+
+
);
@@ -1028,165 +1031,166 @@ function ProvisionsFilter() {
}
function GameModeAbilitiesFilter() {
- const { unwrap } = useLocale();
+ const { unwrap, strings } = useLocale();
const rawAbilities = TankFilters.use((state) => state.abilities);
const rawPowers = TankFilters.use((state) => state.powers);
- const [activeTab, setActiveTab] = useState<"active" | "passive">("active");
- const totalSelected = rawAbilities.length + rawPowers.length;
+ const abilities =
+ rawAbilities.length === 0 && rawPowers.length === 0
+ ? Array.from(allGameModeConsumables.values())
+ : rawAbilities;
+ const powers =
+ rawPowers.length === 0 && rawAbilities.length === 0
+ ? Array.from(allGameModeProvisions.values())
+ : rawPowers;
+
+ const icons = [
+ ...abilities.map((ability) => `icons/consumables/${ability}.webp`),
+ ...powers.map((power) => `icons/provisions/${power}.webp`),
+ ];
return (
-
- {/* Tab buttons */}
-
-
-
-
+
+ {gameModeRoles.map(({ gameModeId, consumables, provisions }) => {
+ const gameMode = gameDefinitions.gameModes[gameModeId];
+ const hasNeither =
+ consumables.length === 0 && provisions.length === 0;
-
+ if (hasNeither) return null;
- {/* Active Abilities Content */}
- {activeTab === "active" && (
- <>
- {gameModeRoles.map(({ gameModeId, consumables }) => {
- const gameMode = gameDefinitions.gameModes[gameModeId];
+ const hasBoth = consumables.length > 0 && provisions.length > 0;
- if (consumables.length === 0) return null;
+ return (
+
+ {consumables.length > 0 && (
+
+ {hasBoth
+ ? literals(strings.website.common.tank_search.active, {
+ name: unwrap(gameMode.name),
+ })
+ : unwrap(gameMode.name)}
+
+ )}
- return (
-
-
- {unwrap(gameMode.name)}
-
+ {consumables.map((consumable) => {
+ {
+ const selected = rawAbilities.includes(consumable);
+ const abilityDefinition =
+ consumableDefinitions.consumables[consumable];
- {consumables.map((consumable) => {
- const selected = rawAbilities.includes(consumable);
- const abilityDefinition =
- consumableDefinitions.consumables[consumable];
+ return (
+ {
+ event.preventDefault();
- return (
- {
- event.preventDefault();
-
- TankFilters.mutate((draft) => {
- if (selected) {
- draft.abilities = draft.abilities.filter(
- (n) => n !== consumable
- );
- } else {
- draft.abilities = [
- ...draft.abilities,
- consumable,
- ];
- }
- });
+ TankFilters.mutate((draft) => {
+ if (selected) {
+ draft.abilities = draft.abilities.filter(
+ (n) => n !== consumable
+ );
+ } else {
+ draft.abilities = [...draft.abilities, consumable];
+ }
+ });
+ }}
+ checked={selected}
+ key={consumable}
+ >
+
-
+ src={asset(`icons/consumables/${consumable}.webp`)}
+ />
- {unwrap(abilityDefinition.name)}
-
- );
- })}
-
- );
- })}
- >
- )}
+ {unwrap(abilityDefinition.name)}
+
+ );
+ }
+ })}
- {/* Passive Abilities Content */}
- {activeTab === "passive" && (
- <>
- {gameModeRoles.map(({ gameModeId, provisions }) => {
- const gameMode = gameDefinitions.gameModes[gameModeId];
+ {provisions.length > 0 && (
+
+ {hasBoth
+ ? literals(strings.website.common.tank_search.passive, {
+ name: unwrap(gameMode.name),
+ })
+ : unwrap(gameMode.name)}
+
+ )}
- if (provisions.length === 0) return null;
+ {provisions.map((provision) => {
+ {
+ const selected = rawPowers.includes(provision);
+ const powerDefinition =
+ provisionDefinitions.provisions[provision];
- return (
-
-
- {unwrap(gameMode.name)}
-
+ return (
+ {
+ event.preventDefault();
- {provisions.map((provision) => {
- const selected = rawPowers.includes(provision);
- const powerDefinition =
- provisionDefinitions.provisions[provision];
-
- return (
- {
- event.preventDefault();
-
- TankFilters.mutate((draft) => {
- if (selected) {
- draft.powers = draft.powers.filter(
- (n) => n !== provision
- );
- } else {
- draft.powers = [...draft.powers, provision];
- }
- });
+ TankFilters.mutate((draft) => {
+ if (selected) {
+ draft.powers = draft.powers.filter(
+ (n) => n !== provision
+ );
+ } else {
+ draft.powers = [...draft.powers, provision];
+ }
+ });
+ }}
+ checked={selected}
+ key={provision}
+ >
+
-
+ src={asset(`icons/provisions/${provision}.webp`)}
+ />
- {unwrap(powerDefinition.name)}
-
- );
- })}
-
- );
- })}
- >
- )}
+ {unwrap(powerDefinition.name)}
+
+ );
+ }
+ })}
+
+ );
+ })}
@@ -1202,7 +1206,7 @@ function GameModeAbilitiesFilter() {
}}
>
- Clear All
+ {strings.website.common.tank_search.clear}