Files
blitzkit/packages/website/src/components/TankSearchSort.tsx
T

148 lines
4.4 KiB
TypeScript
Raw Normal View History

2026-10-31 17:43:57 -05:00
import {
CaretDownIcon,
CaretRightIcon,
DotFilledIcon,
} from "@radix-ui/react-icons";
import { characteristicsGroups } from "../config/characteristicsGroups";
import { useStrings } from "../hooks/useStrings";
import { TankopediaSortDirection } from "../stores/tankopediaPersistent";
import { TankSort } from "../stores/tankopediaSort";
import { sortableCharacteristics } from "../tankopedia/sortableCharacteristics";
import type { CharacteristicName } from "../types/characteristics";
import { Button } from "./Button";
import { DropdownMenu } from "./DropdownMenu";
2024-05-23 13:29:39 -05:00
2025-01-07 13:50:06 -06:00
interface ItemProps {
2026-10-15 00:38:01 -05:00
by: CharacteristicName;
2025-01-07 13:50:06 -06:00
}
function Item({ by }: ItemProps) {
2026-09-27 13:22:34 -05:00
const strings = useStrings();
2026-10-15 00:38:01 -05:00
const selectedBy = TankSort.use((state) => state.by);
2025-01-07 13:50:06 -06:00
return (
<DropdownMenu.CheckboxItem
2026-10-15 00:38:01 -05:00
checked={selectedBy === by}
2025-01-07 13:50:06 -06:00
onClick={() => {
2025-09-01 18:13:41 -05:00
TankSort.mutate((draft) => {
draft.by = by;
});
2025-01-07 13:50:06 -06:00
}}
>
2026-10-31 17:43:57 -05:00
<DropdownMenu.ItemIndicator>
<DotFilledIcon />
</DropdownMenu.ItemIndicator>
2026-10-15 00:38:01 -05:00
{strings.tanks.characteristics.items[by]}
2025-01-07 13:50:06 -06:00
</DropdownMenu.CheckboxItem>
);
}
2026-10-31 17:43:57 -05:00
export function TankSearchSort() {
2026-10-15 00:38:01 -05:00
const by = TankSort.use((state) => state.by);
2025-09-01 18:13:41 -05:00
const direction = TankSort.use((state) => state.direction);
2026-09-27 13:22:34 -05:00
const strings = useStrings();
2024-05-23 13:29:39 -05:00
return (
2026-08-18 13:57:01 -05:00
<DropdownMenu.Root>
2026-08-28 10:42:57 -05:00
<DropdownMenu.Trigger asChild>
<Button variant="surface" color="gray">
2026-10-15 00:38:01 -05:00
{strings.website.common.tank_search.sort.label}
2026-08-28 10:42:57 -05:00
<CaretDownIcon />
</Button>
2024-05-23 13:29:39 -05:00
</DropdownMenu.Trigger>
2024-06-22 16:39:31 -05:00
<DropdownMenu.Content align="end">
2025-01-07 13:50:06 -06:00
<DropdownMenu.Label>
2026-10-31 17:43:57 -05:00
{strings.website.common.tank_search.sort.by}
2025-01-07 13:50:06 -06:00
</DropdownMenu.Label>
2024-05-23 13:29:39 -05:00
2026-10-15 00:38:01 -05:00
<DropdownMenu.CheckboxItem
checked={by === null || !sortableCharacteristics.has(by)}
onClick={() => {
TankSort.mutate((draft) => {
draft.by = null;
});
}}
>
2026-10-31 17:43:57 -05:00
<DropdownMenu.ItemIndicator>
<DotFilledIcon />
</DropdownMenu.ItemIndicator>
2026-10-15 00:38:01 -05:00
{strings.website.common.tank_search.sort.none}
</DropdownMenu.CheckboxItem>
2024-05-23 13:29:39 -05:00
2026-10-15 00:38:01 -05:00
{characteristicsGroups.map((group) => {
const items = group.order.filter(
(item) => "name" in item && sortableCharacteristics.has(item.name),
);
2024-05-23 13:29:39 -05:00
2026-10-15 00:38:01 -05:00
return (
<DropdownMenu.Sub key={group.name}>
<DropdownMenu.SubTrigger>
{
(
strings.tanks.characteristics.titles as Record<
string,
string
>
)[group.name]
}
2026-10-31 17:43:57 -05:00
<CaretRightIcon />
2026-10-15 00:38:01 -05:00
</DropdownMenu.SubTrigger>
2024-05-23 13:29:39 -05:00
2026-10-15 00:38:01 -05:00
<DropdownMenu.SubContent>
{items.map((item) => {
if (!("name" in item)) return null;
return <Item key={item.name} by={item.name} />;
})}
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
);
})}
2024-05-23 13:29:39 -05:00
2025-01-07 13:50:06 -06:00
<DropdownMenu.Label>
2026-10-15 00:38:01 -05:00
{strings.website.common.tank_search.sort.direction.label}
2025-01-07 13:50:06 -06:00
</DropdownMenu.Label>
2024-05-23 13:29:39 -05:00
<DropdownMenu.RadioGroup
2026-10-31 17:43:57 -05:00
value={`${direction}`}
onValueChange={(_value) => {
const value = Number(_value);
2026-10-15 00:38:01 -05:00
if (
value !== TankopediaSortDirection.Ascending &&
value !== TankopediaSortDirection.Descending
) {
throw new Error(`Unknown tankopedia sort direction: ${value}`);
}
2025-09-01 18:13:41 -05:00
TankSort.mutate((draft) => {
2026-10-15 00:38:01 -05:00
draft.direction = value;
2025-09-01 18:13:41 -05:00
});
2024-09-17 22:13:35 -05:00
}}
2024-05-23 13:29:39 -05:00
>
2026-10-31 17:43:57 -05:00
<DropdownMenu.RadioItem
value={`${TankopediaSortDirection.Ascending}`}
>
<DropdownMenu.ItemIndicator>
<DotFilledIcon />
</DropdownMenu.ItemIndicator>
2026-10-15 00:38:01 -05:00
{strings.website.common.tank_search.sort.direction.ascending}
2024-05-23 13:29:39 -05:00
</DropdownMenu.RadioItem>
2026-10-31 17:43:57 -05:00
<DropdownMenu.RadioItem
value={`${TankopediaSortDirection.Descending}`}
>
<DropdownMenu.ItemIndicator>
<DotFilledIcon />
</DropdownMenu.ItemIndicator>
2026-10-15 00:38:01 -05:00
{strings.website.common.tank_search.sort.direction.descending}
2024-05-23 13:29:39 -05:00
</DropdownMenu.RadioItem>
</DropdownMenu.RadioGroup>
</DropdownMenu.Content>
</DropdownMenu.Root>
);
}