Files
gridpilot.gg/apps/website/ui/DashboardHero.tsx
2026-01-17 15:46:55 +01:00

144 lines
4.3 KiB
TypeScript

import React, { ReactNode } from 'react';
import { Box } from './Box';
import { Heading } from './Heading';
import { Image } from './Image';
import { Text } from './Text';
import { Glow } from './Glow';
interface DashboardHeroProps {
driverName: string;
avatarUrl: string;
country: string;
rating: string | number;
rank: string | number;
totalRaces: string | number;
actions?: ReactNode;
stats?: ReactNode;
className?: string;
}
/**
* DashboardHero
*
* Redesigned for "Precision Racing Minimal" theme.
* Uses subtle accent glows and crisp separators.
*/
export function DashboardHero({
driverName,
avatarUrl,
country,
rating,
rank,
totalRaces,
actions,
stats,
className = '',
}: DashboardHeroProps) {
return (
<Box
as="section"
position="relative"
className={`bg-[#0C0D0F] border-b border-[#23272B] overflow-hidden ${className}`}
>
{/* Subtle Accent Glow */}
<Glow
position="top-right"
color="primary"
opacity={0.1}
size="xl"
/>
<Box
maxWidth="80rem"
mx="auto"
px={6}
py={8}
position="relative"
zIndex={1}
>
<Box display="flex" flexDirection="col" gap={8}>
<Box display="flex" align="center" justify="between" wrap gap={6}>
{/* Driver Identity */}
<Box display="flex" align="center" gap={6}>
<Box position="relative">
<Box
w="24"
h="24"
className="border border-[#23272B] p-1 bg-[#141619]"
>
<Image
src={avatarUrl}
alt={driverName}
width={96}
height={96}
className="w-full h-full object-cover grayscale hover:grayscale-0 transition-all duration-300"
/>
</Box>
<Box
position="absolute"
bottom="-1"
right="-1"
w="4"
h="4"
className="bg-[#4ED4E0] border-2 border-[#0C0D0F]"
/>
</Box>
<Box>
<Box display="flex" align="center" gap={3} mb={1}>
<Text size="xs" color="text-gray-500" uppercase weight="bold" letterSpacing="widest">
Driver Profile
</Text>
<Text size="xs" color="text-gray-600">
/
</Text>
<Text size="xs" color="text-gray-400">
{country}
</Text>
</Box>
<Heading level={1} className="text-3xl md:text-4xl font-black uppercase tracking-tighter mb-2">
{driverName}
</Heading>
<Box display="flex" align="center" gap={4}>
<Box display="flex" align="center" gap={2}>
<Text size="xs" color="text-gray-500" uppercase>Rating</Text>
<Text size="sm" weight="bold" className="text-[#4ED4E0] font-mono">{rating}</Text>
</Box>
<Box display="flex" align="center" gap={2}>
<Text size="xs" color="text-gray-500" uppercase>Rank</Text>
<Text size="sm" weight="bold" className="text-[#FFBE4D] font-mono">#{rank}</Text>
</Box>
<Box display="flex" align="center" gap={2}>
<Text size="xs" color="text-gray-500" uppercase>Starts</Text>
<Text size="sm" weight="bold" className="text-gray-300 font-mono">{totalRaces}</Text>
</Box>
</Box>
</Box>
</Box>
{/* Actions */}
{actions && (
<Box display="flex" gap={3}>
{actions}
</Box>
)}
</Box>
{/* Stats Grid */}
{stats && (
<Box
display="grid"
gridCols={2}
responsiveGridCols={{ md: 4 }}
gap={4}
className="border-t border-[#23272B]/50 pt-6"
>
{stats}
</Box>
)}
</Box>
</Box>
</Box>
);
}