website refactor
This commit is contained in:
@@ -9,7 +9,8 @@ interface DriverHeaderPanelProps {
|
||||
avatarUrl?: string;
|
||||
nationality: string;
|
||||
rating: number;
|
||||
globalRank?: number | null;
|
||||
ratingLabel: string;
|
||||
globalRankLabel?: string | null;
|
||||
bio?: string | null;
|
||||
actions?: React.ReactNode;
|
||||
}
|
||||
@@ -19,7 +20,8 @@ export function DriverHeaderPanel({
|
||||
avatarUrl,
|
||||
nationality,
|
||||
rating,
|
||||
globalRank,
|
||||
ratingLabel,
|
||||
globalRankLabel,
|
||||
bio,
|
||||
actions
|
||||
}: DriverHeaderPanelProps) {
|
||||
@@ -54,8 +56,8 @@ export function DriverHeaderPanel({
|
||||
rounded="2xl"
|
||||
overflow="hidden"
|
||||
border
|
||||
borderColor="border-charcoal-outline"
|
||||
bg="bg-graphite-black"
|
||||
borderColor="border-charcoal-outline"
|
||||
bg="bg-graphite-black"
|
||||
flexShrink={0}
|
||||
>
|
||||
<Image
|
||||
@@ -73,16 +75,16 @@ export function DriverHeaderPanel({
|
||||
<Text as="h1" size="3xl" weight="bold" color="text-white">
|
||||
{name}
|
||||
</Text>
|
||||
<RatingBadge rating={rating} size="lg" />
|
||||
<RatingBadge rating={rating} ratingLabel={ratingLabel} size="lg" />
|
||||
</Stack>
|
||||
|
||||
<Stack direction="row" align="center" gap={4} wrap>
|
||||
<Text size="sm" color="text-gray-400">
|
||||
{nationality}
|
||||
</Text>
|
||||
{globalRank !== undefined && globalRank !== null && (
|
||||
{globalRankLabel && (
|
||||
<Text size="sm" color="text-gray-400">
|
||||
Global Rank: <Text color="text-warning-amber" weight="semibold">#{globalRank}</Text>
|
||||
Global Rank: <Text color="text-warning-amber" weight="semibold">{globalRankLabel}</Text>
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
@@ -14,8 +14,10 @@ interface DriverProfileHeaderProps {
|
||||
avatarUrl?: string | null;
|
||||
nationality: string;
|
||||
rating: number;
|
||||
ratingLabel: string;
|
||||
safetyRating?: number;
|
||||
globalRank?: number;
|
||||
safetyRatingLabel: string;
|
||||
globalRankLabel?: string;
|
||||
bio?: string | null;
|
||||
friendRequestSent: boolean;
|
||||
onAddFriend: () => void;
|
||||
@@ -26,8 +28,10 @@ export function DriverProfileHeader({
|
||||
avatarUrl,
|
||||
nationality,
|
||||
rating,
|
||||
ratingLabel,
|
||||
safetyRating = 92,
|
||||
globalRank,
|
||||
safetyRatingLabel,
|
||||
globalRankLabel,
|
||||
bio,
|
||||
friendRequestSent,
|
||||
onAddFriend,
|
||||
@@ -56,11 +60,11 @@ export function DriverProfileHeader({
|
||||
<Stack>
|
||||
<Stack direction="row" align="center" gap={3} mb={1}>
|
||||
<Heading level={1}>{name}</Heading>
|
||||
{globalRank && (
|
||||
{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">
|
||||
<Trophy size={12} color="#FFBE4D" />
|
||||
<Text size="xs" weight="bold" font="mono" color="text-warning-amber">
|
||||
#{globalRank}
|
||||
{globalRankLabel}
|
||||
</Text>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -72,8 +76,8 @@ export function DriverProfileHeader({
|
||||
</Stack>
|
||||
<Stack w="1" h="1" rounded="full" bg="bg-gray-700" />
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<RatingBadge rating={rating} size="sm" />
|
||||
<SafetyRatingBadge rating={safetyRating} size="sm" />
|
||||
<RatingBadge rating={rating} ratingLabel={ratingLabel} size="sm" />
|
||||
<SafetyRatingBadge rating={safetyRating} ratingLabel={safetyRatingLabel} size="sm" />
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -13,7 +13,8 @@ interface DriverTableRowProps {
|
||||
avatarUrl?: string | null;
|
||||
nationality: string;
|
||||
rating: number;
|
||||
wins: number;
|
||||
ratingLabel: string;
|
||||
winsLabel: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
@@ -23,7 +24,8 @@ export function DriverTableRow({
|
||||
avatarUrl,
|
||||
nationality,
|
||||
rating,
|
||||
wins,
|
||||
ratingLabel,
|
||||
winsLabel,
|
||||
onClick,
|
||||
}: DriverTableRowProps) {
|
||||
return (
|
||||
@@ -58,11 +60,11 @@ export function DriverTableRow({
|
||||
<Text size="xs" variant="low">{nationality}</Text>
|
||||
</TableCell>
|
||||
<TableCell textAlign="right">
|
||||
<RatingBadge rating={rating} size="sm" />
|
||||
<RatingBadge rating={rating} ratingLabel={ratingLabel} size="sm" />
|
||||
</TableCell>
|
||||
<TableCell textAlign="right">
|
||||
<Text size="sm" weight="semibold" font="mono" variant="success">
|
||||
{wins}
|
||||
{winsLabel}
|
||||
</Text>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -17,25 +17,25 @@ interface DriverStat {
|
||||
}
|
||||
|
||||
interface DriversDirectoryHeaderProps {
|
||||
totalDrivers: number;
|
||||
activeDrivers: number;
|
||||
totalWins: number;
|
||||
totalRaces: number;
|
||||
totalDriversLabel: string;
|
||||
activeDriversLabel: string;
|
||||
totalWinsLabel: string;
|
||||
totalRacesLabel: string;
|
||||
onViewLeaderboard: () => void;
|
||||
}
|
||||
|
||||
export function DriversDirectoryHeader({
|
||||
totalDrivers,
|
||||
activeDrivers,
|
||||
totalWins,
|
||||
totalRaces,
|
||||
totalDriversLabel,
|
||||
activeDriversLabel,
|
||||
totalWinsLabel,
|
||||
totalRacesLabel,
|
||||
onViewLeaderboard,
|
||||
}: DriversDirectoryHeaderProps) {
|
||||
const stats: DriverStat[] = [
|
||||
{ label: 'drivers', value: totalDrivers, intent: 'primary' },
|
||||
{ label: 'active', value: activeDrivers, intent: 'success' },
|
||||
{ label: 'total wins', value: totalWins.toLocaleString(), intent: 'warning' },
|
||||
{ label: 'races', value: totalRaces.toLocaleString(), intent: 'telemetry' },
|
||||
{ label: 'drivers', value: totalDriversLabel, intent: 'primary' },
|
||||
{ label: 'active', value: activeDriversLabel, intent: 'success' },
|
||||
{ label: 'total wins', value: totalWinsLabel, intent: 'warning' },
|
||||
{ label: 'races', value: totalRacesLabel, intent: 'telemetry' },
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@@ -33,9 +33,9 @@ interface FeaturedDriverCardProps {
|
||||
name: string;
|
||||
nationality: string;
|
||||
avatarUrl?: string;
|
||||
rating: number;
|
||||
wins: number;
|
||||
podiums: number;
|
||||
ratingLabel: string;
|
||||
winsLabel: string;
|
||||
podiumsLabel: string;
|
||||
skillLevel?: string;
|
||||
category?: string;
|
||||
};
|
||||
@@ -142,17 +142,17 @@ export function FeaturedDriverCard({ driver, position, onClick }: FeaturedDriver
|
||||
<Box display="grid" gridCols={3} gap={3}>
|
||||
<MiniStat
|
||||
label="Rating"
|
||||
value={driver.rating.toLocaleString()}
|
||||
value={driver.ratingLabel}
|
||||
color="text-primary-blue"
|
||||
/>
|
||||
<MiniStat
|
||||
label="Wins"
|
||||
value={driver.wins}
|
||||
value={driver.winsLabel}
|
||||
color="text-performance-green"
|
||||
/>
|
||||
<MiniStat
|
||||
label="Podiums"
|
||||
value={driver.podiums}
|
||||
value={driver.podiumsLabel}
|
||||
color="text-warning-amber"
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -17,12 +17,12 @@ interface ProfileHeroProps {
|
||||
avatarUrl?: string;
|
||||
country: string;
|
||||
iracingId: number;
|
||||
joinedAt: string | Date;
|
||||
joinedAtLabel: string;
|
||||
};
|
||||
stats: {
|
||||
rating: number;
|
||||
ratingLabel: string;
|
||||
} | null;
|
||||
globalRank: number;
|
||||
globalRankLabel: string;
|
||||
timezone: string;
|
||||
socialHandles: {
|
||||
platform: string;
|
||||
@@ -47,7 +47,7 @@ function getSocialIcon(platform: string) {
|
||||
export function ProfileHero({
|
||||
driver,
|
||||
stats,
|
||||
globalRank,
|
||||
globalRankLabel,
|
||||
timezone,
|
||||
socialHandles,
|
||||
onAddFriend,
|
||||
@@ -87,14 +87,14 @@ export function ProfileHero({
|
||||
<Surface variant="muted" rounded="lg" padding={1} style={{ backgroundColor: 'rgba(59, 130, 246, 0.1)', border: '1px solid rgba(59, 130, 246, 0.3)', paddingLeft: '0.75rem', paddingRight: '0.75rem' }}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Star style={{ width: '1rem', height: '1rem', color: '#3b82f6' }} />
|
||||
<Text font="mono" weight="bold" color="text-primary-blue">{stats.rating}</Text>
|
||||
<Text font="mono" weight="bold" color="text-primary-blue">{stats.ratingLabel}</Text>
|
||||
<Text size="xs" color="text-gray-400">Rating</Text>
|
||||
</Stack>
|
||||
</Surface>
|
||||
<Surface variant="muted" rounded="lg" padding={1} style={{ backgroundColor: 'rgba(250, 204, 21, 0.1)', border: '1px solid rgba(250, 204, 21, 0.3)', paddingLeft: '0.75rem', paddingRight: '0.75rem' }}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Trophy style={{ width: '1rem', height: '1rem', color: '#facc15' }} />
|
||||
<Text font="mono" weight="bold" style={{ color: '#facc15' }}>#{globalRank}</Text>
|
||||
<Text font="mono" weight="bold" style={{ color: '#facc15' }}>{globalRankLabel}</Text>
|
||||
<Text size="xs" color="text-gray-400">Global</Text>
|
||||
</Stack>
|
||||
</Surface>
|
||||
@@ -111,11 +111,7 @@ export function ProfileHero({
|
||||
<Stack direction="row" align="center" gap={1.5}>
|
||||
<Calendar style={{ width: '1rem', height: '1rem' }} />
|
||||
<Text size="sm">
|
||||
Joined{' '}
|
||||
{new Date(driver.joinedAt).toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
year: 'numeric',
|
||||
})}
|
||||
Joined {driver.joinedAtLabel}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Stack direction="row" align="center" gap={1.5}>
|
||||
|
||||
@@ -3,10 +3,11 @@ import { Badge } from '@/ui/Badge';
|
||||
|
||||
interface RatingBadgeProps {
|
||||
rating: number;
|
||||
ratingLabel: string;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
}
|
||||
|
||||
export function RatingBadge({ rating, size = 'md' }: RatingBadgeProps) {
|
||||
export function RatingBadge({ rating, ratingLabel, size = 'md' }: RatingBadgeProps) {
|
||||
const badgeSize = size === 'lg' ? 'md' : size;
|
||||
|
||||
const getVariant = (val: number): 'warning' | 'primary' | 'success' | 'default' => {
|
||||
@@ -22,7 +23,7 @@ export function RatingBadge({ rating, size = 'md' }: RatingBadgeProps) {
|
||||
variant={getVariant(rating)}
|
||||
size={badgeSize}
|
||||
>
|
||||
{rating.toLocaleString()}
|
||||
{ratingLabel}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ import { Shield } from 'lucide-react';
|
||||
|
||||
interface SafetyRatingBadgeProps {
|
||||
rating: number;
|
||||
ratingLabel: string;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
}
|
||||
|
||||
export function SafetyRatingBadge({ rating, size = 'md' }: SafetyRatingBadgeProps) {
|
||||
export function SafetyRatingBadge({ rating, ratingLabel, size = 'md' }: SafetyRatingBadgeProps) {
|
||||
const getColor = (r: number) => {
|
||||
if (r >= 90) return 'text-performance-green';
|
||||
if (r >= 70) return 'text-warning-amber';
|
||||
@@ -65,7 +66,7 @@ export function SafetyRatingBadge({ rating, size = 'md' }: SafetyRatingBadgeProp
|
||||
font="mono"
|
||||
color={colorClass}
|
||||
>
|
||||
SR {rating.toFixed(0)}
|
||||
{ratingLabel}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user