Session 25: Fix all data rendering — proxy routes, Tank01 normalizer, box-score bridge, inline streaks (1579 tests)
This commit is contained in:
@@ -52,6 +52,14 @@ export interface GameLines {
|
||||
|
||||
export type GameStatus = 'pre' | 'in' | 'post';
|
||||
|
||||
// Session 25 — a computed streak for a player whose team is in this game.
|
||||
export interface GameStreak {
|
||||
player: string;
|
||||
team?: string | null;
|
||||
description: string;
|
||||
currentStreak: number;
|
||||
}
|
||||
|
||||
export interface GameCardProps {
|
||||
sport: SlateSport;
|
||||
homeTeam: string;
|
||||
@@ -73,6 +81,10 @@ export interface GameCardProps {
|
||||
status?: GameStatus;
|
||||
score?: { home: number; away: number } | null;
|
||||
gameLines?: GameLines | null;
|
||||
// Session 25 — streaks for players in THIS game, matched by team in the
|
||||
// Slate. Renders inline below the props/lines so the streak context
|
||||
// lives with the game it belongs to.
|
||||
streaks?: GameStreak[];
|
||||
}
|
||||
|
||||
// Map ESPN status → a compact, human badge. 'in' is live; 'post' is final.
|
||||
@@ -173,11 +185,12 @@ export default function GameCard(props: GameCardProps) {
|
||||
props: propList, gradedProps, loadingKey, errorByKey,
|
||||
tier = 'free', onGrade, onUpgrade,
|
||||
defaultVisible = 4,
|
||||
status, score, gameLines,
|
||||
status, score, gameLines, streaks,
|
||||
} = props;
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const badge = statusBadge(status, score);
|
||||
const bookRows = gameLines?.books ? Object.entries(gameLines.books) : [];
|
||||
const streakRows = (streaks || []).filter((s) => s && s.player && s.description);
|
||||
|
||||
// Session 19 — visibility budget now applies to PLAYERS, not raw
|
||||
// props. Showing the first 4 prop rows that all belonged to the
|
||||
@@ -406,6 +419,40 @@ export default function GameCard(props: GameCardProps) {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Session 25 — streaks for players in THIS game, inline. The Slate
|
||||
matches streaks to games by team, so a card shows the streak
|
||||
context for the players actually on the floor/field. Renders
|
||||
only when there's at least one — no empty section. */}
|
||||
{streakRows.length > 0 && (
|
||||
<div
|
||||
style={{
|
||||
padding: '10px 16px',
|
||||
borderTop: '1px solid var(--border, #1A1A24)',
|
||||
display: 'grid',
|
||||
gap: 6,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="mono"
|
||||
style={{ fontSize: 10, letterSpacing: '0.08em', color: 'var(--text-tertiary, #6B6B7B)', textTransform: 'uppercase' }}
|
||||
>
|
||||
🔥 Streaks
|
||||
</div>
|
||||
{streakRows.map((s) => (
|
||||
<div
|
||||
key={`${s.player}-${s.description}`}
|
||||
style={{ display: 'flex', justifyContent: 'space-between', gap: 12, fontSize: 12, alignItems: 'baseline' }}
|
||||
>
|
||||
<span style={{ color: 'var(--text-0, #F0F0F5)', fontWeight: 600 }}>
|
||||
{s.player}
|
||||
{s.team ? <span style={{ color: 'var(--text-tertiary, #6B6B7B)', fontWeight: 400 }}> · {s.team}</span> : null}
|
||||
</span>
|
||||
<span style={{ color: 'var(--text-secondary, #8A8A9A)', textAlign: 'right' }}>{s.description}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user