code quality
Some checks failed
CI / lint-typecheck (pull_request) Failing after 13s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped

This commit is contained in:
2026-01-27 16:30:03 +01:00
parent 9b31eaf728
commit 9894c4a841
34 changed files with 926 additions and 536 deletions

View File

@@ -57,34 +57,34 @@ export function DashboardTemplate({
return (
<Stack gap={6}>
{/* KPI Overview */}
<DashboardKpiRow items={kpiItems} />
<DashboardKpiRow items={kpiItems} data-testid="dashboard-stats" />
<Grid responsiveGridCols={{ base: 1, lg: 12 }} gap={6}>
{/* Main Content Column */}
<Box responsiveColSpan={{ base: 1, lg: 8 }}>
<Stack direction="col" gap={6}>
{nextRace && (
<TelemetryPanel title="Active Session">
<TelemetryPanel title="Active Session" data-testid="next-race-section">
<Box display="flex" alignItems="center" justifyContent="between">
<Box>
<Text size="xs" variant="low" mb={1} block>Next Event</Text>
<Text size="lg" weight="bold" block>{nextRace.track}</Text>
<Text size="xs" variant="primary" font="mono" block>{nextRace.car}</Text>
<Text size="lg" weight="bold" block data-testid="next-race-track">{nextRace.track}</Text>
<Text size="xs" variant="primary" font="mono" block data-testid="next-race-car">{nextRace.car}</Text>
</Box>
<Box textAlign="right">
<Text size="xs" variant="low" mb={1} block>Starts In</Text>
<Text size="xl" font="mono" weight="bold" variant="warning" block>{nextRace.timeUntil}</Text>
<Text size="xs" variant="low" mb={1} block data-testid="next-race-time">{nextRace.formattedDate} @ {nextRace.formattedTime}</Text>
<Text size="xl" font="mono" weight="bold" variant="warning" block data-testid="next-race-countdown">{nextRace.timeUntil}</Text>
<Text size="xs" variant="low" block>{nextRace.formattedDate} @ {nextRace.formattedTime}</Text>
</Box>
</Box>
</TelemetryPanel>
)}
<TelemetryPanel title="Recent Activity">
<TelemetryPanel title="Recent Activity" data-testid="activity-feed-section">
{hasFeedItems ? (
<RecentActivityTable items={activityItems} />
) : (
<Box py={8} textAlign="center">
<Box py={8} textAlign="center" data-testid="activity-empty">
<Text italic variant="low">No recent activity recorded.</Text>
</Box>
)}
@@ -95,12 +95,22 @@ export function DashboardTemplate({
{/* Sidebar Column */}
<Box responsiveColSpan={{ base: 1, lg: 4 }}>
<Stack direction="col" gap={6}>
<TelemetryPanel title="Championship Standings">
<TelemetryPanel title="Championship Standings" data-testid="championship-standings-section">
{hasLeagueStandings ? (
<Stack direction="col" gap={3}>
{leagueStandings.map((standing) => (
<Box key={standing.leagueId} display="flex" alignItems="center" justifyContent="between" borderBottom borderColor="var(--ui-color-border-muted)" pb={2}>
<Box>
<Box
key={standing.leagueId}
display="flex"
alignItems="center"
justifyContent="between"
borderBottom
borderColor="var(--ui-color-border-muted)"
pb={2}
data-testid={`league-standing-${standing.leagueId}`}
cursor="pointer"
>
<Box data-testid="league-standing-link">
<Text size="xs" weight="bold" truncate block maxWidth="180px">{standing.leagueName}</Text>
<Text size="xs" variant="low" block>Pos: {standing.position} / {standing.totalDrivers}</Text>
</Box>
@@ -109,30 +119,37 @@ export function DashboardTemplate({
))}
</Stack>
) : (
<Box py={4} textAlign="center">
<Box py={4} textAlign="center" data-testid="standings-empty">
<Text italic variant="low">No active championships.</Text>
</Box>
)}
</TelemetryPanel>
<TelemetryPanel title="Upcoming Schedule">
<TelemetryPanel title="Upcoming Schedule" data-testid="upcoming-races-section">
<Stack direction="col" gap={4}>
{upcomingRaces.slice(0, 3).map((race) => (
<Box key={race.id} cursor="pointer">
<Box display="flex" justifyContent="between" alignItems="start" mb={1}>
<Text size="xs" weight="bold">{race.track}</Text>
<Text size="xs" font="mono" variant="low">{race.timeUntil}</Text>
</Box>
<Box display="flex" justifyContent="between">
<Text size="xs" variant="low">{race.car}</Text>
<Text size="xs" variant="low">{race.formattedDate}</Text>
{upcomingRaces.length > 0 ? (
upcomingRaces.slice(0, 3).map((race) => (
<Box key={race.id} cursor="pointer" data-testid={`upcoming-race-${race.id}`}>
<Box display="flex" justifyContent="between" alignItems="start" mb={1} data-testid="upcoming-race-link">
<Text size="xs" weight="bold">{race.track}</Text>
<Text size="xs" font="mono" variant="low">{race.timeUntil}</Text>
</Box>
<Box display="flex" justifyContent="between">
<Text size="xs" variant="low">{race.car}</Text>
<Text size="xs" variant="low">{race.formattedDate}</Text>
</Box>
</Box>
))
) : (
<Box py={4} textAlign="center" data-testid="upcoming-races-empty">
<Text italic variant="low">No upcoming races.</Text>
</Box>
))}
<Button
variant="secondary"
fullWidth
)}
<Button
variant="secondary"
fullWidth
onClick={onNavigateToRaces}
data-testid="view-full-schedule-link"
>
<Text size="xs" weight="bold" uppercase letterSpacing="widest">View Full Schedule</Text>
</Button>

View File

@@ -45,8 +45,8 @@ export function RacesIndexTemplate({
const hasRaces = viewData.racesByDate.length > 0;
return (
<Section variant="default" padding="md">
<PageHeader
<Section variant="default" padding="md" data-testid="races-list">
<PageHeader
title="Races"
description="Live Sessions & Upcoming Events"
icon={Flag}

View File

@@ -42,7 +42,7 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem
title="Welcome Back"
description="Sign in to access your racing dashboard"
>
<AuthForm onSubmit={formActions.handleSubmit}>
<AuthForm onSubmit={formActions.handleSubmit} data-testid="login-form">
<Group direction="column" gap={4} fullWidth>
<Input
label="Email Address"
@@ -56,6 +56,7 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem
disabled={isSubmitting}
autoComplete="email"
icon={<Mail size={16} />}
data-testid="email-input"
/>
<Group direction="column" gap={1.5} fullWidth>
@@ -71,6 +72,7 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem
autoComplete="current-password"
showPassword={viewData.showPassword}
onTogglePassword={() => formActions.setShowPassword(!viewData.showPassword)}
data-testid="password-input"
/>
<Group justify="end" fullWidth>
<Link href={routes.auth.forgotPassword}>
@@ -127,6 +129,7 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem
disabled={isSubmitting}
fullWidth
icon={isSubmitting ? <LoadingSpinner size={4} /> : <LogIn size={16} />}
data-testid="login-submit"
>
{isSubmitting ? 'Signing in...' : 'Sign In'}
</Button>