mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: more filters
This commit is contained in:
1 parent
7020e5641f
commit
b503f4fa8f
5 files changed
+151
-40
No files matched your search
@@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
import { CaretDownIcon } from '@radix-ui/react-icons';
|
import { CaretDownIcon } from '@radix-ui/react-icons';
|
||||||
import { Button, DropdownMenu, Flex } from '@radix-ui/themes';
|
import { Button, DropdownMenu, Flex } from '@radix-ui/themes';
|
||||||
|
import {
|
||||||
|
TANK_TYPES,
|
||||||
|
TREE_TYPES,
|
||||||
|
TREE_TYPE_ICONS,
|
||||||
|
TREE_TYPE_IMAGES,
|
||||||
|
TreeTypeEnum,
|
||||||
|
} from '../../../../components/Tanks';
|
||||||
import {
|
import {
|
||||||
TIERS,
|
TIERS,
|
||||||
TIER_ROMAN_NUMERALS,
|
TIER_ROMAN_NUMERALS,
|
||||||
@@ -16,7 +23,7 @@ export function Options() {
|
|||||||
const tankopediaState = useTankopedia();
|
const tankopediaState = useTankopedia();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex justify="between">
|
<Flex justify="center" wrap="wrap" gap="4">
|
||||||
<Flex gap="1">
|
<Flex gap="1">
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Trigger>
|
||||||
@@ -67,38 +74,110 @@ export function Options() {
|
|||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap="1">
|
<Flex>
|
||||||
<Flex>
|
{TIERS.toReversed().map((tier, index) => (
|
||||||
{TIERS.toReversed().map((tier, index) => (
|
<Button
|
||||||
<Button
|
key={tier}
|
||||||
variant={
|
variant={
|
||||||
tankopediaState.filters.tiers.includes(tier) ? 'solid' : 'soft'
|
tankopediaState.filters.tiers.includes(tier) ? 'solid' : 'soft'
|
||||||
}
|
}
|
||||||
style={{
|
style={{
|
||||||
margin: -0.5,
|
margin: -0.5,
|
||||||
borderTopLeftRadius: index === 0 ? undefined : 0,
|
borderTopLeftRadius: index === 0 ? undefined : 0,
|
||||||
borderBottomLeftRadius: index === 0 ? undefined : 0,
|
borderBottomLeftRadius: index === 0 ? undefined : 0,
|
||||||
borderTopRightRadius:
|
borderTopRightRadius: index === TIERS.length - 1 ? undefined : 0,
|
||||||
index === TIERS.length - 1 ? undefined : 0,
|
borderBottomRightRadius:
|
||||||
borderBottomRightRadius:
|
index === TIERS.length - 1 ? undefined : 0,
|
||||||
index === TIERS.length - 1 ? undefined : 0,
|
}}
|
||||||
}}
|
onClick={() =>
|
||||||
onClick={() =>
|
mutateTankopedia((draft) => {
|
||||||
mutateTankopedia((draft) => {
|
if (draft.filters.tiers.includes(tier)) {
|
||||||
if (draft.filters.tiers.includes(tier)) {
|
draft.filters.tiers = draft.filters.tiers.filter(
|
||||||
draft.filters.tiers = draft.filters.tiers.filter(
|
(preexistingTier) => preexistingTier !== tier,
|
||||||
(preexistingTier) => preexistingTier !== tier,
|
);
|
||||||
);
|
} else {
|
||||||
} else {
|
draft.filters.tiers.push(tier);
|
||||||
draft.filters.tiers.push(tier);
|
}
|
||||||
}
|
})
|
||||||
})
|
}
|
||||||
}
|
>
|
||||||
>
|
{TIER_ROMAN_NUMERALS[tier]}
|
||||||
{TIER_ROMAN_NUMERALS[tier]}
|
</Button>
|
||||||
</Button>
|
))}
|
||||||
))}
|
</Flex>
|
||||||
</Flex>
|
|
||||||
|
<Flex>
|
||||||
|
{TANK_TYPES.toReversed().map((type, index) => (
|
||||||
|
<Button
|
||||||
|
key={type}
|
||||||
|
variant={
|
||||||
|
tankopediaState.filters.types.includes(type) ? 'solid' : 'soft'
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
margin: -0.5,
|
||||||
|
borderTopLeftRadius: index === 0 ? undefined : 0,
|
||||||
|
borderBottomLeftRadius: index === 0 ? undefined : 0,
|
||||||
|
borderTopRightRadius:
|
||||||
|
index === TANK_TYPES.length - 1 ? undefined : 0,
|
||||||
|
borderBottomRightRadius:
|
||||||
|
index === TANK_TYPES.length - 1 ? undefined : 0,
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
mutateTankopedia((draft) => {
|
||||||
|
if (draft.filters.types.includes(type)) {
|
||||||
|
draft.filters.types = draft.filters.types.filter(
|
||||||
|
(preexistingType) => preexistingType !== type,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
draft.filters.types.push(type);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={TREE_TYPE_ICONS[TreeTypeEnum.TechTree][type]}
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex>
|
||||||
|
{TREE_TYPES.map((type, index) => (
|
||||||
|
<Button
|
||||||
|
key={type}
|
||||||
|
variant={
|
||||||
|
tankopediaState.filters.treeTypes.includes(type)
|
||||||
|
? 'solid'
|
||||||
|
: 'soft'
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
margin: -0.5,
|
||||||
|
borderTopLeftRadius: index === 0 ? undefined : 0,
|
||||||
|
borderBottomLeftRadius: index === 0 ? undefined : 0,
|
||||||
|
borderTopRightRadius:
|
||||||
|
index === TREE_TYPES.length - 1 ? undefined : 0,
|
||||||
|
borderBottomRightRadius:
|
||||||
|
index === TREE_TYPES.length - 1 ? undefined : 0,
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
mutateTankopedia((draft) => {
|
||||||
|
if (draft.filters.treeTypes.includes(type)) {
|
||||||
|
draft.filters.treeTypes = draft.filters.treeTypes.filter(
|
||||||
|
(preexistingType) => preexistingType !== type,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
draft.filters.treeTypes.push(type);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={TREE_TYPE_IMAGES[type]}
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,7 +33,18 @@ export default function Page() {
|
|||||||
const searchableTanks = useMemo(
|
const searchableTanks = useMemo(
|
||||||
() =>
|
() =>
|
||||||
awaitedTanks
|
awaitedTanks
|
||||||
.filter((tank) => tankopediaState.filters.tiers.includes(tank.tier))
|
.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)),
|
||||||
|
)
|
||||||
.toSorted((a, b) => {
|
.toSorted((a, b) => {
|
||||||
let diff = 0;
|
let diff = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,18 @@ export enum TreeTypeEnum {
|
|||||||
Collector,
|
Collector,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TankType = 'AT-SPG' | 'lightTank' | 'mediumTank' | 'heavyTank';
|
export const TANK_TYPES = [
|
||||||
export type TreeTypeString = 'tech-tree' | 'premium' | 'collector';
|
'AT-SPG',
|
||||||
|
'lightTank',
|
||||||
|
'mediumTank',
|
||||||
|
'heavyTank',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
// TODO: remove hyphen for underscore
|
||||||
|
export const TREE_TYPES = ['tech-tree', 'premium', 'collector'] as const;
|
||||||
|
|
||||||
|
export type TankType = (typeof TANK_TYPES)[number];
|
||||||
|
export type TreeTypeString = (typeof TREE_TYPES)[number];
|
||||||
|
|
||||||
export const TREE_TYPE_NAMES: Record<TreeTypeString, string> = {
|
export const TREE_TYPE_NAMES: Record<TreeTypeString, string> = {
|
||||||
'tech-tree': 'Tech tree',
|
'tech-tree': 'Tech tree',
|
||||||
@@ -20,6 +30,12 @@ export const TREE_TYPE_NAMES: Record<TreeTypeString, string> = {
|
|||||||
collector: 'Collector',
|
collector: 'Collector',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TREE_TYPE_IMAGES: Record<TreeTypeString, string> = {
|
||||||
|
'tech-tree': 'https://i.imgur.com/pJxO2XY.png',
|
||||||
|
premium: 'https://i.imgur.com/mZzSwOU.png',
|
||||||
|
collector: 'https://i.imgur.com/7A0RsG5.png',
|
||||||
|
};
|
||||||
|
|
||||||
export interface ItemProps {
|
export interface ItemProps {
|
||||||
image?: string;
|
image?: string;
|
||||||
tankType?: TankType;
|
tankType?: TankType;
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ export const TANK_ICONS_COLLECTOR: Record<TankType, string> = {
|
|||||||
heavyTank: 'https://i.imgur.com/8xRf3nc.png',
|
heavyTank: 'https://i.imgur.com/8xRf3nc.png',
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Tier = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
export const TIERS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as const;
|
||||||
|
|
||||||
export const TIERS: Tier[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
export type Tier = (typeof TIERS)[number];
|
||||||
|
|
||||||
export const TIER_ROMAN_NUMERALS: Record<Tier, string> = {
|
export const TIER_ROMAN_NUMERALS: Record<Tier, string> = {
|
||||||
1: 'I',
|
1: 'I',
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { produce } from 'immer';
|
import { produce } from 'immer';
|
||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { TIERS, Tier } from '../core/blitzkrieg/tankopedia';
|
import { TankType, TreeTypeString } from '../components/Tanks';
|
||||||
|
import { Tier } from '../core/blitzkrieg/tankopedia';
|
||||||
|
|
||||||
export type TankopediaSortBy = 'tier' | 'name';
|
export type TankopediaSortBy = 'tier' | 'name';
|
||||||
export type TankopediaSortDirection = 'ascending' | 'descending';
|
export type TankopediaSortDirection = 'ascending' | 'descending';
|
||||||
@@ -13,6 +14,8 @@ type Tankopedia = {
|
|||||||
};
|
};
|
||||||
filters: {
|
filters: {
|
||||||
tiers: Tier[];
|
tiers: Tier[];
|
||||||
|
types: TankType[];
|
||||||
|
treeTypes: TreeTypeString[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,7 +28,9 @@ export const useTankopedia = create<Tankopedia>()(
|
|||||||
direction: 'descending',
|
direction: 'descending',
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
tiers: [...TIERS],
|
tiers: [],
|
||||||
|
types: [],
|
||||||
|
treeTypes: [],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{ name: 'tankopedia' },
|
{ name: 'tankopedia' },
|
||||||
|
|||||||
Reference in new issue
Block a user