mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: better ratings toolbar
This commit is contained in:
1 parent
c83cec8ed7
commit
81c2ca80bc
4 files changed
+131
-44
No files matched your search
+120
-35
@@ -1,26 +1,49 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Flex, Select } from '@radix-ui/themes';
|
import { MagnifyingGlassIcon } from '@radix-ui/react-icons';
|
||||||
|
import { Button, Flex, Popover, Select, TextField } from '@radix-ui/themes';
|
||||||
|
import { range } from 'lodash';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { RatingsInfo } from '../../../commands/ratings';
|
import { RatingsInfo } from '../../../commands/ratings';
|
||||||
import PageWrapper from '../../../components/PageWrapper';
|
import PageWrapper from '../../../components/PageWrapper';
|
||||||
import { Region } from '../../../constants/regions';
|
import { REGIONS, REGION_NAMES, Region } from '../../../constants/regions';
|
||||||
|
import {
|
||||||
|
FIRST_ARCHIVED_RATINGS_SEASON,
|
||||||
|
getLatestArchivedSeasonNumber,
|
||||||
|
} from '../../../core/blitz/getLatestArchivedSeasonNumber';
|
||||||
import getRatingsInfo from '../../../core/blitz/getRatingsInfo';
|
import getRatingsInfo from '../../../core/blitz/getRatingsInfo';
|
||||||
import { RatingsType, useRatings } from '../../../stores/ratings';
|
import { useRatings } from '../../../stores/ratings';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const ratings = useRatings();
|
const ratings = useRatings();
|
||||||
const [awaitedRatingsInfo, setRatingsInfo] = useState<RatingsInfo | null>(
|
const [ratingsInfo, setRatingsInfo] = useState<RatingsInfo | null>(null);
|
||||||
null,
|
const [jumpToLeague, setJumpToLeague] = useState(0);
|
||||||
);
|
const [latestArchivedSeasonNumber, setLatestArchivedSeasonNumber] = useState<
|
||||||
|
number | null
|
||||||
|
>(null);
|
||||||
|
// null being the latest season
|
||||||
|
const [season, setSeason] = useState<null | number>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRatingsInfo(ratings.region).then(setRatingsInfo);
|
(async () => {
|
||||||
|
const [newRatingsInfo, newLatestArchivedSeasonNumber] = await Promise.all(
|
||||||
|
[getRatingsInfo(ratings.region), getLatestArchivedSeasonNumber()],
|
||||||
|
);
|
||||||
|
|
||||||
|
setRatingsInfo(newRatingsInfo);
|
||||||
|
setLatestArchivedSeasonNumber(newLatestArchivedSeasonNumber);
|
||||||
|
|
||||||
|
setSeason(
|
||||||
|
newRatingsInfo.detail == undefined
|
||||||
|
? null
|
||||||
|
: newLatestArchivedSeasonNumber,
|
||||||
|
);
|
||||||
|
})();
|
||||||
}, [ratings.region]);
|
}, [ratings.region]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageWrapper>
|
<PageWrapper>
|
||||||
<Flex gap="2">
|
<Flex gap="2" wrap="wrap">
|
||||||
<Select.Root
|
<Select.Root
|
||||||
defaultValue={ratings.region}
|
defaultValue={ratings.region}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
@@ -30,46 +53,108 @@ export default function Page() {
|
|||||||
<Select.Trigger style={{ flex: 1 }} />
|
<Select.Trigger style={{ flex: 1 }} />
|
||||||
|
|
||||||
<Select.Content>
|
<Select.Content>
|
||||||
<Select.Item value="com">North America</Select.Item>
|
{REGIONS.map((region) => (
|
||||||
<Select.Item value="eu">Europe</Select.Item>
|
<Select.Item key={region} value={region}>
|
||||||
<Select.Item value="asia">Asia</Select.Item>
|
{REGION_NAMES[region]}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select.Root>
|
</Select.Root>
|
||||||
|
|
||||||
<Select.Root
|
<Select.Root
|
||||||
defaultValue={ratings.type}
|
value={`${season}`}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
useRatings.setState({ type: value as RatingsType })
|
setSeason(value === 'null' ? null : parseInt(value))
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Select.Trigger style={{ flex: 1 }} />
|
<Select.Trigger style={{ flex: 1 }} />
|
||||||
|
|
||||||
<Select.Content>
|
<Select.Content>
|
||||||
<Select.Item value="league">League</Select.Item>
|
{ratingsInfo?.detail === undefined && (
|
||||||
<Select.Item value="neighbors">Neighbors</Select.Item>
|
<Select.Item value="null">Current season</Select.Item>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Select.Group>
|
||||||
|
<Select.Label>Archives</Select.Label>
|
||||||
|
|
||||||
|
{latestArchivedSeasonNumber &&
|
||||||
|
range(
|
||||||
|
FIRST_ARCHIVED_RATINGS_SEASON,
|
||||||
|
latestArchivedSeasonNumber + 1,
|
||||||
|
)
|
||||||
|
.map((season) => (
|
||||||
|
<Select.Item key={season} value={`${season}`}>
|
||||||
|
Season {season}
|
||||||
|
</Select.Item>
|
||||||
|
))
|
||||||
|
.reverse()}
|
||||||
|
</Select.Group>
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select.Root>
|
</Select.Root>
|
||||||
|
|
||||||
{ratings.type === 'league' ? (
|
<Popover.Root>
|
||||||
<Select.Root
|
<Popover.Trigger>
|
||||||
defaultValue={`${ratings.league}`}
|
<Button variant="soft">Jump to league</Button>
|
||||||
onValueChange={(value) =>
|
</Popover.Trigger>
|
||||||
useRatings.setState({ league: parseInt(value) })
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Select.Trigger style={{ flex: 1 }} />
|
|
||||||
|
|
||||||
<Select.Content>
|
<Popover.Content>
|
||||||
{awaitedRatingsInfo?.detail === undefined &&
|
<Flex direction="column" gap="2">
|
||||||
awaitedRatingsInfo?.leagues.map((league) => (
|
<Select.Root
|
||||||
<Select.Item key={league.index} value={`${league.index}`}>
|
value={`${jumpToLeague}`}
|
||||||
{league.title}
|
onValueChange={(value) => setJumpToLeague(parseInt(value))}
|
||||||
</Select.Item>
|
>
|
||||||
))}
|
<Select.Trigger />
|
||||||
</Select.Content>
|
|
||||||
</Select.Root>
|
<Select.Content>
|
||||||
) : (
|
{ratingsInfo?.detail === undefined &&
|
||||||
'1'
|
ratingsInfo?.leagues.map(({ index, title }) => (
|
||||||
)}
|
<Select.Item key={index} value={`${index}`}>
|
||||||
|
{title}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
|
||||||
|
<Flex gap="2">
|
||||||
|
<Popover.Close>
|
||||||
|
<Button color="red">Cancel</Button>
|
||||||
|
</Popover.Close>
|
||||||
|
|
||||||
|
<Popover.Close>
|
||||||
|
<Button>Jump</Button>
|
||||||
|
</Popover.Close>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
|
|
||||||
|
<Popover.Root>
|
||||||
|
<Popover.Trigger>
|
||||||
|
<Button variant="soft">Jump to player</Button>
|
||||||
|
</Popover.Trigger>
|
||||||
|
|
||||||
|
<Popover.Content>
|
||||||
|
<Flex gap="2" direction="column">
|
||||||
|
<TextField.Root>
|
||||||
|
<TextField.Slot>
|
||||||
|
<MagnifyingGlassIcon height="16" width="16" />
|
||||||
|
</TextField.Slot>
|
||||||
|
|
||||||
|
<TextField.Input placeholder="Search for player..." />
|
||||||
|
</TextField.Root>
|
||||||
|
|
||||||
|
<Flex gap="2">
|
||||||
|
<Popover.Close>
|
||||||
|
<Button color="red">Cancel</Button>
|
||||||
|
</Popover.Close>
|
||||||
|
|
||||||
|
<Popover.Close>
|
||||||
|
<Button>Jump</Button>
|
||||||
|
</Popover.Close>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
</Flex>
|
</Flex>
|
||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export type Region = 'com' | 'eu' | 'asia';
|
export const REGIONS = ['com', 'eu', 'asia'] as const;
|
||||||
|
|
||||||
|
export type Region = (typeof REGIONS)[number];
|
||||||
export type RegionSubdomain = 'na' | 'eu' | 'asia';
|
export type RegionSubdomain = 'na' | 'eu' | 'asia';
|
||||||
|
|
||||||
export const REGION_NAMES: Record<Region, string> = {
|
export const REGION_NAMES: Record<Region, string> = {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* The first every season that Blitzkrieg tracked :)
|
||||||
|
*/
|
||||||
|
export const FIRST_ARCHIVED_RATINGS_SEASON = 49;
|
||||||
|
|
||||||
|
export async function getLatestArchivedSeasonNumber() {
|
||||||
|
return 51;
|
||||||
|
}
|
||||||
@@ -2,26 +2,18 @@ import { create } from 'zustand';
|
|||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { Region } from '../constants/regions';
|
import { Region } from '../constants/regions';
|
||||||
|
|
||||||
export type RatingsType = 'neighbors' | 'league';
|
|
||||||
|
|
||||||
interface Ratings {
|
interface Ratings {
|
||||||
type: RatingsType;
|
|
||||||
/**
|
/**
|
||||||
* When null, the current season is used unless there ain't one in which case
|
* When null, the current season is used unless there ain't one in which case
|
||||||
* we do whatever lol
|
* we do whatever lol
|
||||||
*/
|
*/
|
||||||
season: number | null;
|
|
||||||
region: Region;
|
region: Region;
|
||||||
league: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useRatings = create<Ratings>()(
|
export const useRatings = create<Ratings>()(
|
||||||
devtools(
|
devtools(
|
||||||
persist(
|
persist(
|
||||||
(set) => ({
|
(set) => ({
|
||||||
type: 'league',
|
|
||||||
season: null,
|
|
||||||
league: 0,
|
|
||||||
region: 'com',
|
region: 'com',
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user