mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 19:56:18 -04:00
fix(#76): surface truthful availability across primary routes
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import { isTimeoutError, userFacingError } from '../lib/fetch'
|
||||
import { noticeMessage, type DataAvailability } from '../lib/availability'
|
||||
|
||||
/** Weekend Context terminology for coverage / availability indicators. */
|
||||
export type DataAvailability = 'local' | 'partial' | 'stale' | 'archive' | 'limited' | 'missing'
|
||||
export type { DataAvailability }
|
||||
|
||||
export function availabilityLabel(kind: DataAvailability): string {
|
||||
switch (kind) {
|
||||
@@ -131,6 +131,7 @@ interface StaleNoticeProps {
|
||||
availability?: DataAvailability
|
||||
message?: string
|
||||
onRetry?: () => void
|
||||
retrying?: boolean
|
||||
testId?: string
|
||||
}
|
||||
|
||||
@@ -139,26 +140,22 @@ export function DataNotice({
|
||||
availability = 'stale',
|
||||
message,
|
||||
onRetry,
|
||||
retrying = false,
|
||||
testId = 'data-notice',
|
||||
}: StaleNoticeProps) {
|
||||
const defaultMessage =
|
||||
availability === 'stale'
|
||||
? 'Showing stale cached data. Retry to refresh.'
|
||||
: availability === 'limited'
|
||||
? 'Some optional details are unavailable. Core local data is shown.'
|
||||
: availability === 'partial'
|
||||
? 'Coverage is partial for this weekend.'
|
||||
: availability === 'archive'
|
||||
? 'Showing an archived snapshot.'
|
||||
: 'Data availability is limited.'
|
||||
|
||||
return (
|
||||
<div className="data-notice" data-testid={testId} role="status">
|
||||
<AvailabilityBadge kind={availability} />
|
||||
<span className="data-notice-text">{message ?? defaultMessage}</span>
|
||||
<span className="data-notice-text">{message ?? noticeMessage(availability)}</span>
|
||||
{onRetry && (
|
||||
<button type="button" className="route-state-retry data-notice-retry" onClick={onRetry}>
|
||||
Retry
|
||||
<button
|
||||
type="button"
|
||||
className="route-state-retry data-notice-retry"
|
||||
onClick={onRetry}
|
||||
disabled={retrying}
|
||||
aria-busy={retrying || undefined}
|
||||
>
|
||||
{retrying ? 'Retrying…' : 'Retry'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -10,9 +10,13 @@ import { meetingIdentity } from '../../lib/weekendContext'
|
||||
* no separate Preview destination. It reuses the existing preview page content and
|
||||
* frames it with the next-session countdown and compact season navigation. It also
|
||||
* backs the /preview alias, so saved preview links resolve here instead of looping.
|
||||
*
|
||||
* Canonical meeting/session identity is passed into Preview so the nested surface
|
||||
* cannot independently re-resolve a different current weekend.
|
||||
*/
|
||||
export function PreSessionView({ context, now }: { context: WeekendContext; now: Date }) {
|
||||
const meeting = meetingIdentity(context.next_meeting ?? context.focus_meeting)
|
||||
const meeting = context.next_meeting ?? context.focus_meeting
|
||||
const identity = meetingIdentity(meeting)
|
||||
const next = context.next_session?.session
|
||||
const nextStart = next?.date_start ?? meeting?.date_start
|
||||
const nodes = railNodes(
|
||||
@@ -25,11 +29,11 @@ export function PreSessionView({ context, now }: { context: WeekendContext; now:
|
||||
<div className="wk-pre" data-testid="weekend-pre-session" data-state="pre_session">
|
||||
<div className="wk-eyebrow mono" data-testid="wk-eyebrow">Pre-session</div>
|
||||
|
||||
{meeting && (
|
||||
{identity && (
|
||||
<header className="wk-pre-head" data-testid="wk-pre-head">
|
||||
<div className="wk-event-id">
|
||||
<Flag code={meeting.country_code} flag={meeting.country_flag} />
|
||||
<h1 className="wk-sessions-title">{meeting.meeting_name}</h1>
|
||||
<Flag code={identity.country_code} flag={identity.country_flag} />
|
||||
<h1 className="wk-sessions-title">{identity.meeting_name}</h1>
|
||||
</div>
|
||||
<div className="wk-pre-countdown">
|
||||
<span className="wk-next-label mono">{next?.session_name ?? 'Next session'}</span>
|
||||
@@ -44,7 +48,11 @@ export function PreSessionView({ context, now }: { context: WeekendContext; now:
|
||||
{nodes.length > 0 && <SessionRail nodes={nodes} />}
|
||||
|
||||
<div className="wk-pre-preview" data-testid="wk-pre-preview">
|
||||
<RacePreviewPage />
|
||||
<RacePreviewPage
|
||||
embedded
|
||||
meeting={meeting}
|
||||
season={context.season ?? meeting?.year}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ChampionshipRoundStrip
|
||||
|
||||
Reference in New Issue
Block a user