Files
vyndr/web/src/lib/emptyState.js
T
builtbykev c8790fde55 Session 57: Phase 0 — Kill the Lies (2309 tests)
Work-order Phase 0 (Jul 10 live audit): every fabricated UI element deleted
or rewired to real data. Deletion sprint — no new product features.

0.1 Fake NBA game: root cause was scheduleService fetching the ESPN
    scoreboard with no ?dates= param or date filter — off-season ESPN
    returns the NEAREST slate (Jun 13 NYK@SA Finals rendered as tonight).
    Now pinned to the requested ET date + defensive filter; undated events
    dropped. Honest month-aware per-sport empty states (lib/emptyState.js).
0.2 Fake header counters: liveTick stripped to a bare 1s pulse (the
    auto-incrementing "247 graded", sin-driven brain-%, aPlus/cascades are
    dead). New GET /api/snapshot/summary (cache-only, before /:sport) +
    Next proxy; HeartbeatBar shows the real graded count and SYNC =
    elapsed since the last pipeline run (amber past 5 min).
0.3 Ticker: hardcoded fallback items deleted (real snapshot exhaust only);
    MOVE kept — computeLineDeltas is real movement. <4 real items → no
    ticker; bar publishes --ticker-h so the fixed header collapses cleanly.
0.4 /terminal retired: route redirects to /dashboard; VVI/injury-wire/
    leaders layouts preserved unrouted as §12 content-engine templates.
    Nav PRIMARY = Slate/Scan/Ledger; BottomTabBar Terminal→Explore; PWA
    shortcut Terminal→Ledger; #terminal alias → /dashboard.
0.5 ›Query nav pill deleted (duplicate /scan link).

Backend 2289 → 2309 tests (199 suites), web build exit 0.
Spec: specs/phase-0-kill-the-lies.md. Next: work-order Phase 1 (ledger
persistence + settlement).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 20:17:49 -04:00

50 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================
Session 57 (Phase 0) — honest per-sport empty-slate copy (spec §6).
A sport with zero games must say WHY instead of showing a fixture game or
passive "waiting" language. Month-aware: an off-season sport names its
return window; an in-season sport calls it an off-day. CommonJS so both the
.tsx surfaces (allowJs) and the plain-JS Jest suite can load it.
============================================================ */
// Off-season months per sport (0-indexed). Deliberately conservative: only
// months where the league is CERTAINLY dark, so an early/late season edge day
// reads as an off-day rather than falsely claiming the league is done.
const OFF_SEASON = {
nba: { months: [6, 7, 8], returns: 'October' }, // JulSep
wnba: { months: [10, 11, 0, 1, 2, 3], returns: 'May' }, // NovApr
mlb: { months: [11, 0, 1], returns: 'spring' }, // DecFeb
};
const LABEL = { nba: 'NBA', wnba: 'WNBA', mlb: 'MLB', soccer: 'Soccer' };
/**
* Copy for an empty slate. `sport` is lowercase ('nba'|'wnba'|'mlb'|'soccer'
* |'all'); anything else falls back to the generic line.
* Returns { title, body }.
*/
function emptyStateCopy(sport, date = new Date()) {
const sp = String(sport || '').toLowerCase();
const month = date.getMonth();
const off = OFF_SEASON[sp];
if (off && off.months.includes(month)) {
return {
title: `${LABEL[sp]} returns in ${off.returns}.`,
body: 'The offseason board is dark. The model is running the live slates in the meantime.',
};
}
if (LABEL[sp]) {
return {
title: `No ${LABEL[sp]} games today.`,
body: 'Off-day. The board refills with the next slate.',
};
}
return {
title: 'No games on the board today.',
body: 'The board refills with the next slate.',
};
}
module.exports = { emptyStateCopy, OFF_SEASON };