code quality
Some checks failed
CI / lint-typecheck (pull_request) Failing after 10s
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 17:36:39 +01:00
parent 9894c4a841
commit e04282d77e
32 changed files with 431 additions and 246 deletions

View File

@@ -1,6 +1,8 @@
'use client';
import React from 'react';
import { useRouter } from 'next/navigation';
import { routes } from '@/lib/routing/RouteConfig';
import { Text } from '@/ui/Text';
import { StatusDot } from '@/ui/StatusDot';
import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from '@/ui/Table';
@@ -23,6 +25,7 @@ interface RecentActivityTableProps {
* A high-density table for displaying recent events and telemetry logs.
*/
export function RecentActivityTable({ items }: RecentActivityTableProps) {
const router = useRouter();
return (
<Table>
<TableHead>
@@ -43,7 +46,12 @@ export function RecentActivityTable({ items }: RecentActivityTableProps) {
</TableHead>
<TableBody>
{items.map((item) => (
<TableRow key={item.id} data-testid={`activity-item-${item.id}`}>
<TableRow
key={item.id}
data-testid={`activity-item-${item.id}`}
cursor="pointer"
onClick={() => router.push(routes.race.results(item.id))}
>
<TableCell data-testid="activity-race-result-link">
<Text font="mono" variant="telemetry" size="xs">{item.type}</Text>
</TableCell>

View File

@@ -27,10 +27,12 @@ interface DriverCardProps {
export function DriverCard({ driver, onClick }: DriverCardProps) {
return (
<ProfileCard
data-testid="driver-card"
onClick={() => onClick(driver.id)}
variant="muted"
identity={
<DriverIdentity
data-testid="driver-identity"
driver={{
id: driver.id,
name: driver.name,
@@ -41,7 +43,7 @@ export function DriverCard({ driver, onClick }: DriverCardProps) {
/>
}
actions={
<Badge variant="outline" size="sm">
<Badge data-testid="driver-rating" variant="outline" size="sm">
{driver.ratingLabel}
</Badge>
}

View File

@@ -45,7 +45,7 @@ export function DriverProfileHeader({
<Stack position="relative" display="flex" flexDirection={{ base: 'col', lg: 'row' }} gap={8}>
{/* Avatar */}
<Stack position="relative" h={{ base: '32', lg: '40' }} w={{ base: '32', lg: '40' }} flexShrink={0} overflow="hidden" rounded="2xl" border={true} borderWidth="2px" borderColor="border-charcoal-outline" bg="bg-deep-graphite" shadow="2xl">
<Stack data-testid="driver-profile-avatar" position="relative" h={{ base: '32', lg: '40' }} w={{ base: '32', lg: '40' }} flexShrink={0} overflow="hidden" rounded="2xl" border={true} borderWidth="2px" borderColor="border-charcoal-outline" bg="bg-deep-graphite" shadow="2xl">
<Image
src={avatarUrl || defaultAvatar}
alt={name}
@@ -59,9 +59,9 @@ export function DriverProfileHeader({
<Stack display="flex" flexDirection={{ base: 'col', lg: 'row' }} alignItems={{ lg: 'center' }} justifyContent="between" gap={2}>
<Stack>
<Stack direction="row" align="center" gap={3} mb={1}>
<Heading level={1}>{name}</Heading>
<Heading data-testid="driver-profile-name" level={1}>{name}</Heading>
{globalRankLabel && (
<Stack display="flex" alignItems="center" gap={1} rounded="md" bg="bg-warning-amber/10" px={2} py={0.5} border borderColor="border-warning-amber/20">
<Stack data-testid="driver-profile-rank" display="flex" alignItems="center" gap={1} rounded="md" bg="bg-warning-amber/10" px={2} py={0.5} border borderColor="border-warning-amber/20">
<Trophy size={12} color="#FFBE4D" />
<Text size="xs" weight="bold" font="mono" color="text-warning-amber">
{globalRankLabel}
@@ -70,7 +70,7 @@ export function DriverProfileHeader({
)}
</Stack>
<Stack direction="row" align="center" gap={4}>
<Stack direction="row" align="center" gap={1.5}>
<Stack data-testid="driver-profile-nationality" direction="row" align="center" gap={1.5}>
<Globe size={14} color="#6B7280" />
<Text size="sm" color="text-gray-400">{nationality}</Text>
</Stack>
@@ -95,7 +95,7 @@ export function DriverProfileHeader({
</Stack>
{bio && (
<Stack maxWidth="3xl">
<Stack data-testid="driver-profile-bio" maxWidth="3xl">
<Text size="sm" color="text-gray-400" leading="relaxed">
{bio}
</Text>

View File

@@ -27,6 +27,7 @@ export function DriverProfileTabs({ activeTab, onTabChange }: DriverProfileTabsP
return (
<Box
as="button"
data-testid={`profile-tab-${tab.id}`}
key={tab.id}
onClick={() => onTabChange(tab.id)}
position="relative"

View File

@@ -16,17 +16,18 @@ interface DriverStatsPanelProps {
export function DriverStatsPanel({ stats }: DriverStatsPanelProps) {
return (
<Box display="grid" gridCols={{ base: 2, sm: 3, lg: 6 }} gap="px" overflow="hidden" rounded="xl" border borderColor="border-charcoal-outline" bg="bg-charcoal-outline">
<Box data-testid="driver-stats-panel-grid" display="grid" gridCols={{ base: 2, sm: 3, lg: 6 }} gap="px" overflow="hidden" rounded="xl" border borderColor="border-charcoal-outline" bg="bg-charcoal-outline">
{stats.map((stat, index) => (
<Box key={index} display="flex" flexDirection="col" gap={1} bg="bg-deep-charcoal" p={5} transition hoverBg="bg-deep-charcoal/80">
<Text size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">
<Box key={index} data-testid={`stat-item-${stat.label.toLowerCase().replace(/\s+/g, '-')}`} display="flex" flexDirection="col" gap={1} bg="bg-deep-charcoal" p={5} transition hoverBg="bg-deep-charcoal/80">
<Text data-testid={`stat-label-${stat.label.toLowerCase().replace(/\s+/g, '-')}`} size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">
{stat.label}
</Text>
<Box display="flex" alignItems="baseline" gap={1.5}>
<Text
size="2xl"
weight="bold"
font="mono"
<Text
data-testid={`stat-value-${stat.label.toLowerCase().replace(/\s+/g, '-')}`}
size="2xl"
weight="bold"
font="mono"
color={stat.color || 'text-white'}
>
{stat.value}

View File

@@ -46,9 +46,10 @@ export function NotFoundScreen({
<NotFoundDiagnostics errorCode={errorCode} />
<Group direction="column" align="center" gap={4} fullWidth>
<Text
<Text
as="h1"
size="4xl"
data-testid="error-title"
size="4xl"
weight="bold"
variant="high"
uppercase

View File

@@ -21,6 +21,7 @@ export function ProfileTabs({ activeTab, onTabChange }: ProfileTabsProps) {
return (
<SegmentedControl
data-testid="profile-tabs"
options={options}
activeId={activeTab}
onChange={(id) => onTabChange(id as ProfileTab)}