Add championship what-if simulator

Fourth view on the championship page: assign P1-P10 per remaining
round and see projected standings update live, with position deltas
and mathematically alive/eliminated title states. Pure projection
logic in lib/simulator.ts (2025 points system, standard GPs only);
scenarios persist to localStorage per season. 169 frontend tests
passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 00:31:09 -04:00
parent e5cb4e4ed2
commit 5cfaed30ba
8 changed files with 1013 additions and 1 deletions

View File

@@ -4,3 +4,26 @@ Object.defineProperty(window, 'scrollTo', {
value: () => {},
writable: true,
})
// Node 22+ ships an experimental `localStorage` global that shadows jsdom's
// implementation; without `--localstorage-file` it resolves to undefined in
// the test environment. Back-fill a minimal in-memory Storage so components
// that persist state (e.g. the championship simulator) are testable.
if (typeof window !== 'undefined' && !window.localStorage) {
const store = new Map<string, string>()
const localStorageMock: Storage = {
get length() {
return store.size
},
clear: () => store.clear(),
getItem: (key) => (store.has(key) ? store.get(key)! : null),
key: (index) => [...store.keys()][index] ?? null,
removeItem: (key) => {
store.delete(key)
},
setItem: (key, value) => {
store.set(String(key), String(value))
},
}
Object.defineProperty(window, 'localStorage', { value: localStorageMock, writable: true })
}