diff --git a/frontend/src/components/WeekendSwitcher.tsx b/frontend/src/components/WeekendSwitcher.tsx index edbeb07..aa024fc 100644 --- a/frontend/src/components/WeekendSwitcher.tsx +++ b/frontend/src/components/WeekendSwitcher.tsx @@ -47,7 +47,7 @@ export function WeekendSwitcher({ currentMeetingKey, currentSessionKey, onClose } return ( -
+
Switch Weekend
diff --git a/frontend/src/pages/RaceHubPage.tsx b/frontend/src/pages/RaceHubPage.tsx index 3e7ec26..fb84eeb 100644 --- a/frontend/src/pages/RaceHubPage.tsx +++ b/frontend/src/pages/RaceHubPage.tsx @@ -102,7 +102,16 @@ export function RaceHubPage({ sessionKey }: Props) { ) } if (preSession && preSessionRef) { - return + return ( + setSwitcherOpen((open) => !open)} + onCloseSwitcher={() => setSwitcherOpen(false)} + /> + ) } if (!selectedSessionKey) { return ( @@ -350,7 +359,21 @@ export function RaceHubPage({ sessionKey }: Props) { ) } -function RaceHubPreSession({ session, weekend, now }: { session: ContextSession; weekend?: Weekend; now: number }) { +function RaceHubPreSession({ + session, + weekend, + now, + switcherOpen, + onToggleSwitcher, + onCloseSwitcher, +}: { + session: ContextSession + weekend?: Weekend + now: number + switcherOpen: boolean + onToggleSwitcher: () => void + onCloseSwitcher: () => void +}) { const meeting = session.meeting const sessions = sortSessionsByStart((weekend?.sessions ?? []).map((entry) => entry.session)) const target = new Date(session.session.date_start) @@ -359,6 +382,29 @@ function RaceHubPreSession({ session, weekend, now }: { session: ContextSession; return (
+
+ box-box · race hub + + +
+ + {switcherOpen && ( + + )} +
box-box · race hub

{meeting?.meeting_name ?? 'Next race weekend'}

diff --git a/frontend/src/test/RaceHubPage.test.tsx b/frontend/src/test/RaceHubPage.test.tsx index 8eeca29..cbadde5 100644 --- a/frontend/src/test/RaceHubPage.test.tsx +++ b/frontend/src/test/RaceHubPage.test.tsx @@ -311,6 +311,30 @@ describe('RaceHubPage', () => { expect(mockFetchRaceHub).not.toHaveBeenCalled() }) + it('opens the weekend switcher from pre-session and navigates to the selected explicit session', async () => { + mockFetchWeekendContext.mockResolvedValue({ + ...analysisContext, + race_hub_default_session: { + session: { ...raceSession, session_key: 9473, session_name: 'Practice 1', session_type: 'Practice', date_start: '2099-05-23T13:00:00Z' }, + meeting, + availability, + }, + race_hub_pre_session: true, + race_hub_refresh_at: '2099-05-23T13:00:00Z', + }) + + renderRaceHub(0) + + const switchWeekend = await screen.findByTestId('rh-switch-weekend') + expect(switchWeekend).toHaveAttribute('aria-expanded', 'false') + fireEvent.click(switchWeekend) + expect(await screen.findByTestId('rh-switcher')).toBeInTheDocument() + expect(switchWeekend).toHaveAttribute('aria-expanded', 'true') + + fireEvent.click(await screen.findByTestId('rh-switcher-session-9471')) + await waitFor(() => expect(window.location.search).toBe('?session_key=9471')) + }) + it('shows recovery instead of selecting an empty future session', async () => { mockFetchWeekendContext.mockResolvedValue({ ...analysisContext, diff --git a/tests/race-hub.spec.ts b/tests/race-hub.spec.ts index c27458e..dbf9fe1 100644 --- a/tests/race-hub.spec.ts +++ b/tests/race-hub.spec.ts @@ -175,6 +175,28 @@ test.describe('Race Hub Weekend Workspace', () => { expect(raceHubRequests).not.toContain(9473) }) + test('pre-session state opens the weekend switcher and navigates to an explicit session', async ({ page }) => { + await page.route('**/api/v1/weekend-context', (route) => + route.fulfill({ + contentType: 'application/json', + body: JSON.stringify(pendingContext('2030-01-01T00:00:16Z')), + }), + ) + + await page.goto('/race-hub') + await expect(page.getByTestId('race-hub-pre-session')).toBeVisible() + + const switchWeekend = page.getByTestId('rh-switch-weekend') + await expect(switchWeekend).toHaveAttribute('aria-expanded', 'false') + await switchWeekend.click() + await expect(page.getByTestId('rh-switcher')).toBeVisible() + await expect(switchWeekend).toHaveAttribute('aria-expanded', 'true') + + await page.getByTestId(`rh-switcher-session-${FULL_SESSION}`).click() + await expect(page).toHaveURL(new RegExp(`/race-hub\\?session_key=${FULL_SESSION}`)) + await expect(page.getByTestId('race-hub')).toBeVisible() + }) + test('bare /race-hub recovers when no completed local analysis exists', async ({ page }) => { await page.route('**/api/v1/weekend-context', (route) => route.fulfill({