mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 19:56:18 -04:00
fix(#73): consume canonical Weekend Context contract and repair navigation
Address the independent review blockers on PR #80 after rebasing onto the authoritative #72 Weekend Context API. - Replace the invented frontend WeekendContext with the exact backend contract (temporal_state, previous/focus/next meetings, previous_completed/active/next/ default_analysis sessions with availability). Every valid canonical payload now maps to a designed state via a total resolveViewState; a well-formed response can never fall through to the limited-data placeholder. - Make the canonical read the single source of truth: useWeekendContext no longer fans out to season/meetings/per-weekend/OpenF1/live queries. Only supplementary championship + news reads run, and only once the canonical context resolves. - Fix the Prepare/analysis flow: /preview is a stable alias that renders the preparation surface (PreSessionView) instead of redirecting back to the same between-races screen. - One primary navigation system per breakpoint: the mobile top-bar links are hidden so the bottom bar is the sole primary nav, and Admin is moved out of every Primary landmark into an operator-utilities toolbar. - Add Vitest coverage for the contract mapping, every temporal state, loading/ error/limited surfaces, the no-fanout guarantee, the /preview CTA, and the nav hierarchy; add hermetic Playwright journeys (seeded + injected canonical payloads), 390/768/1440 overflow checks, and Weekend visual snapshots. Retire the stale Command Center specs/snapshots. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,40 +1,45 @@
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { ChevronRight, Radio } from 'lucide-react'
|
||||
import type { WeekendContext } from '../../types'
|
||||
import { EventPodium, Flag, SessionTimeline } from './shared'
|
||||
import { EventPodium, Flag, SessionRail, railNodes } from './shared'
|
||||
import { analysisSessionKey, meetingIdentity } from '../../lib/weekendContext'
|
||||
|
||||
export function LiveHandoffView({ context }: { context: WeekendContext }) {
|
||||
const { active_meeting_name, active_circuit_short_name, sessions, last_session } = context
|
||||
const liveSession = sessions?.find((s) => s.status === 'live')
|
||||
const focus = meetingIdentity(context.focus_meeting ?? context.active_session?.meeting)
|
||||
const active = context.active_session?.session
|
||||
const previous = context.previous_completed_session
|
||||
const previousName = previous?.session.session_name ?? 'Last session'
|
||||
const analysisKey = analysisSessionKey(context)
|
||||
const nodes = railNodes(previous, context.active_session, context.next_session)
|
||||
|
||||
return (
|
||||
<div className="wk-live" data-testid="weekend-live" data-state={context.state}>
|
||||
<div className="wk-live" data-testid="weekend-live" data-state="session_live">
|
||||
<div className="wk-eyebrow mono" data-testid="wk-eyebrow">Session live</div>
|
||||
|
||||
<section className="wk-live-card" data-testid="wk-live-card">
|
||||
<div className="wk-live-head">
|
||||
<div className="wk-event-id">
|
||||
<Flag code={context.last_event?.country_code} flag={context.last_event?.country_flag} />
|
||||
<h1 className="wk-sessions-title">{active_meeting_name ?? 'Live session'}</h1>
|
||||
<Flag code={focus?.country_code} flag={focus?.country_flag} />
|
||||
<h1 className="wk-sessions-title">{focus?.meeting_name ?? 'Live session'}</h1>
|
||||
</div>
|
||||
<span className="wk-live-pulse" aria-hidden="true" />
|
||||
</div>
|
||||
{active_circuit_short_name && <p className="wk-sessions-circuit mono">{active_circuit_short_name}</p>}
|
||||
{focus?.circuit_short_name && <p className="wk-sessions-circuit mono">{focus.circuit_short_name}</p>}
|
||||
<p className="wk-live-lead">
|
||||
{liveSession ? `${liveSession.session_name} is on track now.` : 'A session is running now.'}
|
||||
{active?.session_name ? `${active.session_name} is on track now.` : 'A session is running now.'}
|
||||
</p>
|
||||
<Link to="/live" className="wk-cta wk-cta-primary wk-cta-wide" data-testid="wk-watch-live">
|
||||
<Radio size={15} aria-hidden="true" /> Watch live timing <ChevronRight size={15} aria-hidden="true" />
|
||||
</Link>
|
||||
</section>
|
||||
|
||||
{sessions && <SessionTimeline sessions={sessions} />}
|
||||
<SessionRail nodes={nodes} />
|
||||
|
||||
{last_session && (
|
||||
{previous && (
|
||||
<section className="wk-recap-card" data-testid="wk-last-session">
|
||||
<span className="wk-recap-eyebrow mono">{last_session.label} · Complete</span>
|
||||
<h2 className="wk-recap-title">What happened in {last_session.label}</h2>
|
||||
<EventPodium event={last_session} />
|
||||
<span className="wk-recap-eyebrow mono">{previousName} · Complete</span>
|
||||
<h2 className="wk-recap-title">What happened in {previousName}</h2>
|
||||
<EventPodium sessionKey={analysisKey} />
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user