Skip to content

Commit d3cdb09

Browse files
authored
bug: fix elo in header (#372)
1 parent 5e08f01 commit d3cdb09

2 files changed

Lines changed: 80 additions & 28 deletions

File tree

components/PlayerEloHistoryDialog.vue

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ const chartSeries = computed(() => {
218218
219219
const stats = computed(() => {
220220
const list = filteredHistory.value;
221+
// Headline ELO values (current/peak/lowest) anchor to Competitive when
222+
// no specific mode is chosen — otherwise the most recent Wingman/Duel
223+
// match would flip "Current ELO" away from the player's primary mode.
224+
const headlineList =
225+
selectedMode.value === "all"
226+
? history.value.filter((e) => e.type === "Competitive")
227+
: list;
221228
if (list.length === 0) {
222229
return {
223230
current: null as number | null,
@@ -245,7 +252,7 @@ const stats = computed(() => {
245252
let worstLoss: EloEntry | null = null;
246253
let peakEntry: EloEntry | null = null;
247254
248-
for (const e of list) {
255+
for (const e of headlineList) {
249256
const elo = e.updated_elo ?? e.current_elo ?? null;
250257
if (elo !== null) {
251258
if (elo > peak) {
@@ -254,6 +261,9 @@ const stats = computed(() => {
254261
}
255262
if (elo < lowest) lowest = elo;
256263
}
264+
}
265+
266+
for (const e of list) {
257267
if (e.match_result === "won" || e.match_result === "win") wins++;
258268
else if (e.match_result === "lost" || e.match_result === "loss") losses++;
259269
else if (e.match_result === "tied" || e.match_result === "tie") ties++;
@@ -267,7 +277,7 @@ const stats = computed(() => {
267277
}
268278
}
269279
270-
const last = list[list.length - 1];
280+
const last = headlineList[headlineList.length - 1];
271281
const decided = wins + losses;
272282
return {
273283
current: last?.updated_elo ?? last?.current_elo ?? null,
@@ -384,86 +394,118 @@ function fmtDate(iso: string | null | undefined): string {
384394
</div>
385395
</div>
386396

387-
<!-- Fixed cell heights — keeps the strip a stable height when
388-
optional subtext rows ("Peak Nov 9 2025", "—") toggle in/out
389-
between data states, which prevents the dialog from re-centering. -->
397+
<!-- Every cell is a 3-row stack (label / value / subtext) with the
398+
same min-height. Cells without a real subtext render an &nbsp;
399+
placeholder so the value baseline lines up across the whole
400+
strip — otherwise Current/Lowest visually float to the top of
401+
their cells next to Peak/Matches/Win Rate. -->
390402
<div
391403
class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-px bg-border/40 border-b border-border/50"
392404
>
393-
<div class="bg-card/60 min-h-[78px] px-4 py-3">
405+
<div
406+
class="bg-card/60 min-h-[96px] px-4 py-4 flex flex-col justify-center gap-1.5"
407+
>
394408
<div
395409
class="font-mono text-[0.55rem] uppercase tracking-[0.22em] text-muted-foreground"
396410
>
397411
{{ $t("pages.players.detail.elo_history_dialog.current") }}
398412
</div>
399-
<div class="mt-1 text-xl font-bold tabular-nums">
413+
<div
414+
class="text-2xl sm:text-3xl font-bold leading-none tabular-nums tracking-tight"
415+
>
400416
{{ fmtInt(stats.current) }}
401417
</div>
418+
<div
419+
class="font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
420+
>
421+
&nbsp;
422+
</div>
402423
</div>
403-
<div class="bg-card/60 min-h-[78px] px-4 py-3">
424+
<div
425+
class="bg-card/60 min-h-[96px] px-4 py-4 flex flex-col justify-center gap-1.5"
426+
>
404427
<div
405428
class="font-mono text-[0.55rem] uppercase tracking-[0.22em] text-muted-foreground inline-flex items-center gap-1"
406429
>
407430
<Crown class="h-3 w-3 text-[hsl(var(--tac-amber))]" />
408431
{{ $t("pages.players.detail.elo_history_dialog.peak") }}
409432
</div>
410433
<div
411-
class="mt-1 text-xl font-bold tabular-nums text-[hsl(var(--tac-amber))]"
434+
class="text-2xl sm:text-3xl font-bold leading-none tabular-nums tracking-tight text-[hsl(var(--tac-amber))]"
412435
>
413436
{{ fmtInt(stats.peak) }}
414437
</div>
415438
<div
416-
v-if="stats.peakEntry"
417-
class="mt-0.5 font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
439+
class="font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
418440
>
419-
{{ fmtDate(stats.peakEntry.match_created_at) }}
441+
<template v-if="stats.peakEntry">{{
442+
fmtDate(stats.peakEntry.match_created_at)
443+
}}</template>
444+
<template v-else>&nbsp;</template>
420445
</div>
421446
</div>
422-
<div class="bg-card/60 min-h-[78px] px-4 py-3">
447+
<div
448+
class="bg-card/60 min-h-[96px] px-4 py-4 flex flex-col justify-center gap-1.5"
449+
>
423450
<div
424451
class="font-mono text-[0.55rem] uppercase tracking-[0.22em] text-muted-foreground"
425452
>
426453
{{ $t("pages.players.detail.elo_history_dialog.lowest") }}
427454
</div>
428-
<div class="mt-1 text-xl font-bold tabular-nums">
455+
<div
456+
class="text-2xl sm:text-3xl font-bold leading-none tabular-nums tracking-tight"
457+
>
429458
{{ fmtInt(stats.lowest) }}
430459
</div>
460+
<div
461+
class="font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
462+
>
463+
&nbsp;
464+
</div>
431465
</div>
432-
<div class="bg-card/60 min-h-[78px] px-4 py-3">
466+
<div
467+
class="bg-card/60 min-h-[96px] px-4 py-4 flex flex-col justify-center gap-1.5"
468+
>
433469
<div
434470
class="font-mono text-[0.55rem] uppercase tracking-[0.22em] text-muted-foreground"
435471
>
436472
{{ $t("pages.players.detail.elo_history_dialog.matches") }}
437473
</div>
438-
<div class="mt-1 text-xl font-bold tabular-nums">
474+
<div
475+
class="text-2xl sm:text-3xl font-bold leading-none tabular-nums tracking-tight"
476+
>
439477
{{ stats.total.toLocaleString() }}
440478
</div>
441479
<div
442-
v-if="stats.total > 0"
443-
class="mt-0.5 font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
480+
class="font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
444481
>
445-
<span class="text-green-500">{{ stats.wins }}W</span>
446-
·
447-
<span class="text-red-500">{{ stats.losses }}L</span>
448-
<template v-if="stats.ties > 0">
449-
· <span>{{ stats.ties }}T</span>
482+
<template v-if="stats.total > 0">
483+
<span class="text-green-500">{{ stats.wins }}W</span>
484+
·
485+
<span class="text-red-500">{{ stats.losses }}L</span>
486+
<template v-if="stats.ties > 0">
487+
· <span>{{ stats.ties }}T</span>
488+
</template>
450489
</template>
490+
<template v-else>&nbsp;</template>
451491
</div>
452492
</div>
453-
<div class="bg-card/60 px-4 py-3 col-span-2 sm:col-span-1">
493+
<div
494+
class="bg-card/60 min-h-[96px] px-4 py-4 col-span-2 sm:col-span-1 flex flex-col justify-center gap-1.5"
495+
>
454496
<div
455497
class="font-mono text-[0.55rem] uppercase tracking-[0.22em] text-muted-foreground"
456498
>
457499
{{ $t("pages.players.detail.elo_history_dialog.win_rate") }}
458500
</div>
459501
<div
460-
class="mt-1 text-xl font-bold tabular-nums"
502+
class="text-2xl sm:text-3xl font-bold leading-none tabular-nums tracking-tight"
461503
:class="stats.winPct >= 50 ? 'text-green-500' : 'text-red-500'"
462504
>
463505
{{ stats.total > 0 ? stats.winPct.toFixed(1) + "%" : "—" }}
464506
</div>
465507
<div
466-
class="mt-0.5 font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
508+
class="font-mono text-[0.55rem] uppercase tracking-[0.18em] text-muted-foreground"
467509
>
468510
{{ $t("pages.players.detail.elo_history_dialog.avg_delta_elo") }}
469511
<span

pages/players/[id].vue

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,13 @@ const modeFilteredWindowed = computed<WindowedEloEntry[]>(() => {
370370
371371
const windowedStats = computed(() => {
372372
const list = modeFilteredWindowed.value;
373+
// Headline ELO values (current/peak/lowest) anchor to Competitive when
374+
// no specific mode is chosen — otherwise the most recent Wingman/Duel
375+
// match would flip "Current ELO" away from the player's primary mode.
376+
const headlineList =
377+
selectedModeRef.value === "all"
378+
? eloHistory.value.filter((e) => e.type === "Competitive")
379+
: list;
373380
if (list.length === 0) {
374381
return {
375382
current: null as number | null,
@@ -405,7 +412,7 @@ const windowedStats = computed(() => {
405412
let worstLoss: WindowedEloEntry | null = null;
406413
let peakEntry: WindowedEloEntry | null = null;
407414
408-
for (const e of list) {
415+
for (const e of headlineList) {
409416
const elo = e.updated_elo ?? e.current_elo ?? null;
410417
if (elo !== null) {
411418
if (elo > peak) {
@@ -414,6 +421,9 @@ const windowedStats = computed(() => {
414421
}
415422
if (elo < lowest) lowest = elo;
416423
}
424+
}
425+
426+
for (const e of list) {
417427
if (e.match_result === "won" || e.match_result === "win") wins++;
418428
else if (e.match_result === "lost" || e.match_result === "loss") losses++;
419429
else if (e.match_result === "tied" || e.match_result === "tie") ties++;
@@ -431,7 +441,7 @@ const windowedStats = computed(() => {
431441
assists += e.assists ?? 0;
432442
}
433443
434-
const last = list[list.length - 1];
444+
const last = headlineList[headlineList.length - 1];
435445
const current = last?.updated_elo ?? last?.current_elo ?? null;
436446
const decided = wins + losses;
437447
const kd = deaths > 0 ? kills / deaths : kills;

0 commit comments

Comments
 (0)