112 lines
3.9 KiB
TypeScript
112 lines
3.9 KiB
TypeScript
|
|
|
|
import { Card } from '@/ui/Card';
|
|
import { CircularProgress } from '@/ui/CircularProgress';
|
|
import { Heading } from '@/ui/Heading';
|
|
import { HorizontalBarChart } from '@/ui/HorizontalBarChart';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { Grid } from '@/ui/Grid';
|
|
import { GridItem } from '@/ui/GridItem';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Text } from '@/ui/Text';
|
|
import { Activity, BarChart3, Target, TrendingUp } from 'lucide-react';
|
|
|
|
interface PerformanceOverviewProps {
|
|
stats: {
|
|
wins: number;
|
|
podiums: number;
|
|
totalRaces: number;
|
|
consistency: number | null;
|
|
dnfs: number;
|
|
bestFinish: number;
|
|
avgFinish: number | null;
|
|
};
|
|
}
|
|
|
|
export function PerformanceOverview({ stats }: PerformanceOverviewProps) {
|
|
return (
|
|
<Card>
|
|
<Stack mb={6}>
|
|
<Heading level={2} icon={<Icon icon={Activity} size={5} intent="telemetry" />}>
|
|
Performance Overview
|
|
</Heading>
|
|
</Stack>
|
|
<Grid cols={12} gap={8}>
|
|
<GridItem colSpan={12} lgSpan={6}>
|
|
<Stack align="center" gap={4}>
|
|
<Stack direction="row" gap={6}>
|
|
<CircularProgress
|
|
value={stats.wins}
|
|
max={stats.totalRaces}
|
|
label="Win Rate"
|
|
color="var(--ui-color-intent-success)"
|
|
/>
|
|
<CircularProgress
|
|
value={stats.podiums}
|
|
max={stats.totalRaces}
|
|
label="Podium Rate"
|
|
color="var(--ui-color-intent-warning)"
|
|
/>
|
|
</Stack>
|
|
<Stack direction="row" gap={6}>
|
|
<CircularProgress
|
|
value={stats.consistency ?? 0}
|
|
max={100}
|
|
label="Consistency"
|
|
color="var(--ui-color-intent-primary)"
|
|
/>
|
|
<CircularProgress
|
|
value={stats.totalRaces - stats.dnfs}
|
|
max={stats.totalRaces}
|
|
label="Finish Rate"
|
|
color="var(--ui-color-intent-telemetry)"
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
</GridItem>
|
|
|
|
<GridItem colSpan={12} lgSpan={6}>
|
|
<Stack mb={4}>
|
|
<Heading level={3} icon={<Icon icon={BarChart3} size={4} intent="low" />}>
|
|
Results Breakdown
|
|
</Heading>
|
|
</Stack>
|
|
<HorizontalBarChart
|
|
data={[
|
|
{ label: 'Wins', value: stats.wins, color: 'var(--ui-color-intent-success)' },
|
|
{ label: 'Podiums (2nd-3rd)', value: stats.podiums - stats.wins, color: 'var(--ui-color-intent-warning)' },
|
|
{ label: 'DNFs', value: stats.dnfs, color: 'var(--ui-color-intent-critical)' },
|
|
]}
|
|
maxValue={stats.totalRaces}
|
|
/>
|
|
|
|
<Stack mt={6}>
|
|
<Grid cols={2} gap={4}>
|
|
<Stack p={4} bg="var(--ui-color-bg-base)" rounded="xl" border borderColor="var(--ui-color-border-low)">
|
|
<Stack gap={2}>
|
|
<Stack direction="row" align="center" gap={2}>
|
|
<Icon icon={TrendingUp} size={4} intent="success" />
|
|
<Text size="xs" variant="low" uppercase>Best Finish</Text>
|
|
</Stack>
|
|
<Text size="2xl" weight="bold" variant="success">P{stats.bestFinish}</Text>
|
|
</Stack>
|
|
</Stack>
|
|
<Stack p={4} bg="var(--ui-color-bg-base)" rounded="xl" border borderColor="var(--ui-color-border-low)">
|
|
<Stack gap={2}>
|
|
<Stack direction="row" align="center" gap={2}>
|
|
<Icon icon={Target} size={4} intent="primary" />
|
|
<Text size="xs" variant="low" uppercase>Avg Finish</Text>
|
|
</Stack>
|
|
<Text size="2xl" weight="bold" variant="primary">
|
|
P{(stats.avgFinish ?? 0).toFixed(1)}
|
|
</Text>
|
|
</Stack>
|
|
</Stack>
|
|
</Grid>
|
|
</Stack>
|
|
</GridItem>
|
|
</Grid>
|
|
</Card>
|
|
);
|
|
}
|