feat: updated /fullstats with figma

This commit is contained in:
TresAbhi committed 2023-07-11 19:43:22 +00:00
1 parent fedad8df3e
commit 21158e9081
10 files changed
+246 -67

No files matched your search

+3 -3
View File
@@ -2,8 +2,8 @@
What is considered a "day's worth of games" is determined by the reset time. The reset time is generally at midnight everyday after which newer games are counted towards the next day. Reset times vary from region to region:
- North America: UTC-5:00 (Central North American Time midnight)
- Europe: UTC+1:00 (Central European Time midnight)
- Asia: UTC+7:00 (Central Asia Standard Time midnight)
- North America: `UTC-5:00` (Central North American Time midnight)
- Europe: `UTC+1:00` (Central European Time midnight)
- Asia: `UTC+7:00` (Central Asia Standard Time midnight)
**Reset times are different from Blitz Stars** (Blitz Stars resets at 5:00 am locally relative to the user opening their website). Inconsistencies with Blitz Stars only occur with sleep-deprived players and players who play in the wrong region.
+1 -1
View File
@@ -19,7 +19,7 @@ import { AccountInfo } from '../types/accountInfo.js';
export const fullStatsCommand: CommandRegistry = {
inProduction: true,
inDevelopment: false,
inDevelopment: true,
inPublic: true,
command: addStatTypeSubCommandGroups(
+1 -1
View File
@@ -33,7 +33,7 @@ function addDocsSubcommands(option: SlashCommandSubcommandsOnlyBuilder) {
export const helpCommand: CommandRegistry = {
inProduction: true,
inDevelopment: true,
inDevelopment: false,
inPublic: true,
command: addDocsSubcommands(
-60
View File
@@ -1,60 +0,0 @@
import getWN8Percentile from '../core/blitz/getWN8Percentile.js';
import isNumber from '../core/node/isNumber.js';
import { AllStats, SupplementaryStats } from '../types/accountInfo.js';
import GenericStats from './GenericStats/index.js';
export interface GenericAllStatsProps {
stats: AllStats;
supplementaryStats?: SupplementaryStats;
}
export default function GenericAllStats({
stats,
supplementaryStats,
}: GenericAllStatsProps) {
const damageRatio = stats.damage_dealt / stats.damage_received;
const killsToDeathRatio =
stats.frags / (stats.battles - stats.survived_battles);
return (
<GenericStats
stats={[
['Winrate', `${(100 * (stats.wins / stats.battles)).toFixed(2)}%`],
[
'WN8',
supplementaryStats
? isNumber(supplementaryStats.WN8)
? supplementaryStats.WN8!.toFixed(0)
: '--'
: undefined,
isNumber(supplementaryStats?.WN8)
? getWN8Percentile(supplementaryStats!.WN8!)
: undefined,
],
[
'Survival',
`${(100 * (stats.survived_battles / stats.battles)).toFixed(2)}%`,
],
['Accuracy', `${((stats.hits / stats.shots) * 100).toFixed(2)}%`],
['Battles', stats.battles],
['Wins', stats.wins],
['Losses', stats.losses],
['Average damage', (stats.damage_dealt / stats.battles).toFixed(0)],
[
'Average tier',
supplementaryStats?.tier ? supplementaryStats?.tier.toFixed(2) : '--',
],
['Average XP', (stats.xp / stats.battles).toFixed(0)],
['Average shots', (stats.shots / stats.battles).toFixed(2)],
['Average hits', (stats.hits / stats.battles).toFixed(2)],
['Average kills', (stats.frags / stats.battles).toFixed(2)],
['Average spots', (stats.spotted / stats.battles).toFixed(2)],
['Damage ratio', isFinite(damageRatio) ? damageRatio.toFixed(2) : '--'],
[
'Kills to death ratio',
isFinite(killsToDeathRatio) ? killsToDeathRatio.toFixed(2) : '--',
],
]}
/>
);
}
@@ -0,0 +1,91 @@
import { Percentile } from '../../../constants/percentiles.js';
import { theme } from '../../../stitches.config.js';
import PercentileIndicator from '../../PercentileIndicator.js';
export interface CardItem {
label: string;
value: string | number | undefined;
percentile?: Percentile;
}
export interface CardProps {
items: CardItem[];
title: string;
}
export function Card({ items, title }: CardProps) {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 16,
flex: 1,
borderRadius: 4,
backgroundColor: theme.colors.componentInteractive,
padding: 8,
}}
>
<span
style={{
color: theme.colors.textHighContrast,
fontSize: 24,
}}
>
{title}
</span>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 8,
}}
>
{items.map((item) => (
<div
style={{
display: 'flex',
gap: 8,
alignItems: 'center',
justifyContent: 'center',
}}
>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
{item.label}
</span>
<div
style={{
flex: 1,
height: 1,
borderRadius: 0.5,
backgroundColor: theme.colors.borderNonInteractive,
}}
/>
<div
style={{
display: 'flex',
gap: 4,
alignItems: 'center',
justifyContent: 'center',
}}
>
{item.percentile !== undefined && (
<PercentileIndicator percentile={item.percentile} />
)}
<span
style={{ fontSize: 16, color: theme.colors.textHighContrast }}
>
{item.value === undefined || Number.isNaN(item.value)
? '--'
: item.value}
</span>
</div>
</div>
))}
</div>
</div>
);
}
@@ -0,0 +1,17 @@
export interface RootProps {
children: React.ReactNode;
}
export function Root({ children }: RootProps) {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 8,
}}
>
{children}
</div>
);
}
@@ -0,0 +1,7 @@
export interface RowProps {
children: React.ReactNode;
}
export function Row({ children }: RowProps) {
return <div style={{ display: 'flex', gap: 8 }}>{children}</div>;
}
+124
View File
@@ -0,0 +1,124 @@
import getWN8Percentile from '../../core/blitz/getWN8Percentile.js';
import isNumber from '../../core/node/isNumber.js';
import { AllStats, SupplementaryStats } from '../../types/accountInfo.js';
import { Card } from './components/Card.js';
import { Root } from './components/Root.js';
import { Row } from './components/Row.js';
// TODO: remove the .js endings
export interface GenericAllStatsProps {
stats: AllStats;
supplementaryStats?: SupplementaryStats;
}
export default function GenericAllStats({
stats,
supplementaryStats,
}: GenericAllStatsProps) {
const damageRatio = stats.damage_dealt / stats.damage_received;
const killsToDeathRatio =
stats.frags / (stats.battles - stats.survived_battles);
return (
<Root>
<Row>
<Card
title="Games"
items={[
{
label: 'Winrate',
value: `${(100 * (stats.wins / stats.battles)).toFixed(2)}%`,
},
{
label: 'Battles',
value: stats.battles,
},
{
label: 'Wins / Losses',
value: `${stats.wins} / ${stats.losses}`,
},
]}
/>
<Card
title="Efficiency"
items={[
{
label: 'WN8',
value:
supplementaryStats && isNumber(supplementaryStats.WN8)
? supplementaryStats.WN8!.toFixed(0)
: undefined,
percentile: isNumber(supplementaryStats?.WN8)
? getWN8Percentile(supplementaryStats!.WN8!)
: undefined,
},
{
label: 'Survival',
value: `${(
100 *
(stats.survived_battles / stats.battles)
).toFixed(2)}%`,
},
{
label: 'Accuracy',
value: `${((stats.hits / stats.shots) * 100).toFixed(2)}%`,
},
]}
/>
</Row>
<Row>
<Card
title="Lethality"
items={[
{
label: 'Average damage',
value: (stats.damage_dealt / stats.battles).toFixed(0),
},
{
label: 'Damage per tier',
value: supplementaryStats?.tier
? (
stats.damage_dealt /
stats.battles /
supplementaryStats.tier
).toFixed(0)
: undefined,
},
{
label: 'Damage ratio',
value: isFinite(damageRatio) ? damageRatio.toFixed(2) : undefined,
},
{
label: 'Average kills',
value: (stats.frags / stats.battles).toFixed(0),
},
]}
/>
<Card
title="Efficiency"
items={[
{
label: 'Average tier',
value: supplementaryStats?.tier?.toFixed(2),
},
{
label: 'Average spots',
value: (stats.spotted / stats.battles).toFixed(2),
},
{
label: 'Average XP',
value: (stats.xp / stats.battles).toFixed(0),
},
{
label: 'Kills to death ratio',
value: isFinite(killsToDeathRatio)
? killsToDeathRatio.toFixed(2)
: undefined,
},
]}
/>
</Row>
</Root>
);
}
+1 -1
View File
@@ -1,4 +1,4 @@
import GenericAllStats from '../components/GenericAllStats.js';
import GenericAllStats from '../components/GenericAllStats/index.js';
import NoData, { NoDataType } from '../components/NoData.js';
import PoweredBy, { PoweredByType } from '../components/PoweredBy.js';
import TierWeights, { TierWeightsRecord } from '../components/TierWeights.js';
+1 -1
View File
@@ -5,7 +5,7 @@ import { RouteRegistry } from '../server.js';
export const todayRoute: RouteRegistry = {
route: '/today',
inProduction: true,
inDevelopment: true,
inDevelopment: false,
async handler(req) {
const player = resolvePlayerFromRequest(req);