mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 11:54:59 -04:00
fix(#98): expose weekend switcher before sessions
This commit is contained in:
@@ -47,7 +47,7 @@ export function WeekendSwitcher({ currentMeetingKey, currentSessionKey, onClose
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rh-switcher" data-testid="rh-switcher">
|
<div id="rh-weekend-switcher" className="rh-switcher" data-testid="rh-switcher">
|
||||||
<div className="rh-switcher-head">
|
<div className="rh-switcher-head">
|
||||||
<span className="sec-title">Switch Weekend</span>
|
<span className="sec-title">Switch Weekend</span>
|
||||||
<div className="rh-switcher-years">
|
<div className="rh-switcher-years">
|
||||||
|
|||||||
@@ -102,7 +102,16 @@ export function RaceHubPage({ sessionKey }: Props) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (preSession && preSessionRef) {
|
if (preSession && preSessionRef) {
|
||||||
return <RaceHubPreSession session={preSessionRef} weekend={preSessionWeekendQuery.data} now={now} />
|
return (
|
||||||
|
<RaceHubPreSession
|
||||||
|
session={preSessionRef}
|
||||||
|
weekend={preSessionWeekendQuery.data}
|
||||||
|
now={now}
|
||||||
|
switcherOpen={switcherOpen}
|
||||||
|
onToggleSwitcher={() => setSwitcherOpen((open) => !open)}
|
||||||
|
onCloseSwitcher={() => setSwitcherOpen(false)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (!selectedSessionKey) {
|
if (!selectedSessionKey) {
|
||||||
return (
|
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 meeting = session.meeting
|
||||||
const sessions = sortSessionsByStart((weekend?.sessions ?? []).map((entry) => entry.session))
|
const sessions = sortSessionsByStart((weekend?.sessions ?? []).map((entry) => entry.session))
|
||||||
const target = new Date(session.session.date_start)
|
const target = new Date(session.session.date_start)
|
||||||
@@ -359,6 +382,29 @@ function RaceHubPreSession({ session, weekend, now }: { session: ContextSession;
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rh-page rh-empty" data-testid="race-hub-pre-session" style={{ '--gp-accent': accent } as React.CSSProperties}>
|
<div className="rh-page rh-empty" data-testid="race-hub-pre-session" style={{ '--gp-accent': accent } as React.CSSProperties}>
|
||||||
|
<div className="rh-topbar">
|
||||||
|
<span className="rh-topbar-label mono">box-box · race hub</span>
|
||||||
|
<span className="rh-topbar-spacer" />
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`rh-switcher-toggle${switcherOpen ? ' active' : ''}`}
|
||||||
|
onClick={onToggleSwitcher}
|
||||||
|
aria-expanded={switcherOpen}
|
||||||
|
aria-controls="rh-weekend-switcher"
|
||||||
|
data-testid="rh-switch-weekend"
|
||||||
|
>
|
||||||
|
{switcherOpen ? 'Close' : 'Switch Weekend'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{switcherOpen && (
|
||||||
|
<WeekendSwitcher
|
||||||
|
currentMeetingKey={meeting?.meeting_key}
|
||||||
|
currentSessionKey={session.session.session_key}
|
||||||
|
onClose={onCloseSwitcher}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<section className="rh-empty-band">
|
<section className="rh-empty-band">
|
||||||
<span className="rh-empty-eyebrow mono">box-box · race hub</span>
|
<span className="rh-empty-eyebrow mono">box-box · race hub</span>
|
||||||
<h1 className="rh-empty-title">{meeting?.meeting_name ?? 'Next race weekend'}</h1>
|
<h1 className="rh-empty-title">{meeting?.meeting_name ?? 'Next race weekend'}</h1>
|
||||||
|
|||||||
@@ -311,6 +311,30 @@ describe('RaceHubPage', () => {
|
|||||||
expect(mockFetchRaceHub).not.toHaveBeenCalled()
|
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 () => {
|
it('shows recovery instead of selecting an empty future session', async () => {
|
||||||
mockFetchWeekendContext.mockResolvedValue({
|
mockFetchWeekendContext.mockResolvedValue({
|
||||||
...analysisContext,
|
...analysisContext,
|
||||||
|
|||||||
@@ -175,6 +175,28 @@ test.describe('Race Hub Weekend Workspace', () => {
|
|||||||
expect(raceHubRequests).not.toContain(9473)
|
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 }) => {
|
test('bare /race-hub recovers when no completed local analysis exists', async ({ page }) => {
|
||||||
await page.route('**/api/v1/weekend-context', (route) =>
|
await page.route('**/api/v1/weekend-context', (route) =>
|
||||||
route.fulfill({
|
route.fulfill({
|
||||||
|
|||||||
Reference in New Issue
Block a user