refactor(stats): centralise good/bad trend logic in format.ts#317
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors session-page stat trend rendering by centralizing “bad stat” semantics and trend direction/sentiment logic into src/stats/format.ts, aligning with the earlier formatting consolidation in #316.
Changes:
- Added
BAD_STATS,isBadStat,getTrendDirection, andgetTrendSentimenttosrc/stats/format.ts. - Updated session route components to use shared trend direction/sentiment helpers plus a local (MUI-only)
SENTIMENT_COLORmapping. - Added unit tests covering bad-stat classification and trend direction/sentiment helpers.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/stats/format.ts | Centralizes bad-stat semantics and shared trend direction/sentiment helpers. |
| src/routes/session/$uuid.tsx | Replaces duplicated trend logic with shared helpers and a route-local sentiment→MUI-color map. |
| src/stats/format.unit.test.ts | Adds unit coverage for isBadStat, getTrendDirection, and getTrendSentiment. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
e7edcdb to
e38738a
Compare
Move the good/bad stat semantics next to the stat-kind formatting knowledge from #316: BAD_STATS now lives in src/stats/format.ts alongside a new isBadStat helper, plus the two pure trend primitives that were previously open-coded twice in the session route: - getTrendDirection(from, to): three-way up/down/flat comparison - getTrendSentiment(stat, direction): good/bad/neutral, folding in isBadStat SessionStatCard and ProgressionValueAndMilestone each duplicated both the numeric->direction if/else chain and the (direction, isBad)->colour mapping. Both now derive direction/sentiment from the shared helpers and map the sentiment to a MUI colour through a single module-level SENTIMENT_COLOR record. Behaviour-preserving. Adds src/stats/format.unit.test.ts covering the new pure helpers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e38738a to
60ff204
Compare
Amund211
added a commit
that referenced
this pull request
Jul 10, 2026
The detail page hand-rolled stat formatting: .toFixed(2) for FKDR/KDR and Math.round(x * 100) + "%" for win rate, duplicating the stat-kind knowledge that #316/#317 centralised behind formatStatValue. Route the FKDR/KDR/win-rate/stars values (cards, mode breakdown, chart tooltip, highlights) through it so precision and locale formatting stay in one place. Win rate now shows one decimal (e.g. 42.0%) instead of a rounded integer, and decimals pick up locale grouping — matching the sessions list and history chart. Derived, non-stat values (durations, k XP, fk/hr, the FKDR axis ticks, and the LinearProgress numeric prop) are left as-is. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Follows the pattern of #316 (which introduced
src/stats/format.tsas the single home for stat-kind formatting knowledge) by moving the good/bad stat functionality into that same shared helper file, and consolidating the trend logic that was open-coded in two places on the session page.Moved into
src/stats/format.tsBAD_STATS+isBadStat(stat)— previously a module-level constant insrc/routes/session/$uuid.tsx. This is stat semantics (which stats get error colours when rising), so it now sits next toSTAT_FORMAT_KIND.getTrendDirection(from, to)— the three-wayup/down/flatnumeric comparison, which was open-coded as an identicalif/elsechain in bothSessionStatCardandProgressionValueAndMilestone.getTrendSentiment(stat, direction)—good/bad/neutral, folding inisBadStat. This is the(direction, isBad) → good/badrule that was duplicated (as an inline(dir === "up") === badStatexpression) at both call sites.Call sites
SessionStatCardandProgressionValueAndMilestoneeach did the same two steps — compare two numbers into a direction, then map(direction, isBad)to a MUI colour. Both now:The MUI-specific
sentiment → colormapping (good → success,bad → error,neutral → undefined) is a single module-levelSENTIMENT_COLORrecord in the route (kept out offormat.tsso the shared file stays free of MUI). The change is behaviour-preserving — same colours, same icons.Other consolidation candidates (left out, deliberately)
isLinearStat/getRelatedStats— pure stat metadata, but each is used in only one file ($uuid.tsx), so moving them would be relocation without de-duplication. Happy to move them if you'd prefer all stat metadata to live informat.ts.ProgressionCaption's inline.toLocaleString(undefined, { min/maxFractionDigits: 2 })— repeated ~20× for per-day rates. These are rate values, not stat values, so they don't map to aStatKeyformat kind; unifying them is a larger refactor and there's already aTODOon the quotient cases. Out of scope here.Test plan
pnpm tsc+pnpm tsc:node— cleanpnpm lint:check(oxlint + oxfmt) — cleanpnpm test:unit— 786 pass (incl. newsrc/stats/format.unit.test.tscoveringisBadStat/getTrendDirection/getTrendSentiment)pnpm test(browser) — 987 pass🤖 Generated with Claude Code