'use client'; import { ArrowDownIcon, InfoCircledIcon, MagnifyingGlassIcon, } from '@radix-ui/react-icons'; import { AlertDialog, Button, Card, Flex, Heading, Link, Table, Text, TextField, } from '@radix-ui/themes'; import { debounce } from 'lodash'; import { use, useEffect, useMemo, useRef, useState } from 'react'; import PageWrapper from '../../../components/PageWrapper'; import { UNLOCALIZED_REGION_NAMES_SHORT } from '../../../constants/regions'; import { authURL } from '../../../core/blitz/authURL'; import { generateStats, prettifyStats, STAT_NAMES, } from '../../../core/blitz/generateStats'; import { getAccountInfo, IndividualAccountInfo, } from '../../../core/blitz/getAccountInfo'; import getTankStats from '../../../core/blitz/getTankStats'; import { idToRegion } from '../../../core/blitz/idToRegion'; import searchPlayersAcrossRegions, { AccountListWithServer, } from '../../../core/blitz/searchPlayersAcrossRegions'; import { tankDefinitions } from '../../../core/blitzkit/tankDefinitions'; import { tankIcon } from '../../../core/blitzkit/tankIcon'; import { tankAverages } from '../../../core/blitzstars/tankAverages'; import { deltaTankStats } from '../../../core/statistics/deltaTankStats'; import { theme } from '../../../stitches.config'; import { useApp } from '../../../stores/app'; import mutateSession, { SessionTracking, useSession, } from '../../../stores/session'; import { IndividualTankStats } from '../../../types/tanksStats'; export default function Page() { const awaitedTankDefinitions = use(tankDefinitions); const awaitedTankAvearges = use(tankAverages); const [showSearch, setShowSearch] = useState(false); const [searching, setSearching] = useState(false); const [searchResults, setSearchResults] = useState([]); const [showFurtherVerification, setShowFurtherVerification] = useState(false); const input = useRef(null); const session = useSession(); const login = useApp((state) => state.login); const [tankStatsB, setTankStatsB] = useState( null, ); const accountInfoPromise = useMemo( () => new Promise(async (resolve) => { resolve( session.tracking ? await getAccountInfo(session.player.region, session.player.id) : null, ); }), [session.tracking && session.player.id], ); const accountInfo = use(accountInfoPromise); const delta = useMemo( () => session.tracking && tankStatsB ? deltaTankStats(session.player.stats, tankStatsB).sort( (a, b) => b.last_battle_time - a.last_battle_time, ) : undefined, [session.tracking && session.player, tankStatsB], ); const search = debounce(async () => { if (!input.current) return; setSearchResults(await searchPlayersAcrossRegions(input.current.value, 9)); setSearching(false); }, 500); useEffect(() => { (async () => { if (!session.tracking || !input.current) return; let accountInfo = await getAccountInfo( session.player.region, session.player.id, ); let tankStats = await getTankStats( session.player.region, session.player.id, ); if (accountInfo === null) { if (login?.id === session.player.id) { accountInfo = await getAccountInfo( idToRegion(session.player.id), session.player.id, [], { access_token: login.token }, ); tankStats = await getTankStats( idToRegion(session.player.id), session.player.id, { access_token: login.token }, ); console.log(accountInfo, tankStats); input.current.value = accountInfo.nickname; } else { setShowFurtherVerification(true); } } })(); if (session.tracking) { const interval = setInterval(async () => { const tankStats = await getTankStats( idToRegion(session.player.id), session.player.id, ); setTankStatsB(tankStats); // TODO: make refresh rate configurable }, 1000); return () => clearInterval(interval); } }, [session.tracking && session.player.id]); return ( {/* omit totally to avoid accessing undefined player */} {showFurtherVerification && ( We need further verification You're trying to track a CC account which have private statistics. Please sign in to verify the ownership of this account. Individual tank statistics won't be available. {login && ( You are currently signed with a different account. )} )} {!session.tracking && ( Look up a player to get started { if (!input.current) return; const sanitized = input.current.value.trim(); if (sanitized.length > 0) { setShowSearch(true); setSearching(true); search(); } else { setShowSearch(false); } }} > {showSearch && ( {searching && ( Searching... )} {!searching && searchResults.length === 0 && ( No players found )} {!searching && searchResults.length > 0 && ( {searchResults.map((player) => ( ))} )} )} )} {session.tracking && ( Tracking {accountInfo?.nickname} Since {new Date(session.player.since).toLocaleString()} )} {session.tracking && delta && delta.length > 0 && ( Tank {session.columns.map((column) => ( {STAT_NAMES[column]} ))} {delta.map((entry) => { const tank = awaitedTankDefinitions[entry.tank_id]; const average = awaitedTankAvearges[tank.id]; const stats = prettifyStats( generateStats(entry.all, average?.all), ); return (
{tank.name} {session.columns.map((column) => ( {stats[column]} ))} ); })} )} {session.tracking && delta && delta.length === 0 && ( No battles Go ahead and play a game )} ); }