Files
gridpilot.gg/apps/website/components/races/RaceUserResult.tsx
2026-01-14 23:46:04 +01:00

93 lines
4.5 KiB
TypeScript

'use client';
import React from 'react';
import { Trophy } from 'lucide-react';
import { Surface } from '@/ui/Surface';
import { Stack } from '@/ui/Stack';
import { Box } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { DecorativeBlur } from '@/ui/DecorativeBlur';
interface RaceUserResultProps {
position: number;
startPosition: number;
positionChange: number;
incidents: number;
isClean: boolean;
isPodium: boolean;
ratingChange?: number;
animatedRatingChange: number;
}
export function RaceUserResult({
position,
startPosition,
positionChange,
incidents,
isClean,
isPodium,
ratingChange,
animatedRatingChange,
}: RaceUserResultProps) {
return (
<Surface
variant={position === 1 ? 'gradient-gold' : isPodium ? 'muted' : 'gradient-blue'}
rounded="2xl"
padding={1}
style={{ background: position === 1 ? 'linear-gradient(to right, #eab308, #facc15, #d97706)' : isPodium ? 'linear-gradient(to right, #9ca3af, #d1d5db, #6b7280)' : 'linear-gradient(to right, #3b82f6, #60a5fa, #2563eb)' }}
>
<Surface variant="dark" rounded="xl" padding={8} style={{ position: 'relative' }}>
<DecorativeBlur color="blue" size="lg" position="top-right" opacity={10} />
<Stack direction="row" align="center" justify="between" wrap gap={6} style={{ position: 'relative', zIndex: 10 }}>
<Stack direction="row" align="center" gap={5}>
<Box style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', width: '7rem', height: '7rem', borderRadius: '1.5rem', fontWeight: 900, fontSize: '3rem', background: position === 1 ? 'linear-gradient(to bottom right, #facc15, #d97706)' : position === 2 ? 'linear-gradient(to bottom right, #d1d5db, #6b7280)' : 'linear-gradient(to bottom right, #3b82f6, #2563eb)', color: position <= 2 ? '#0f1115' : 'white', boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1)' }}>
{position === 1 && (
<Trophy style={{ position: 'absolute', top: '-0.75rem', right: '-0.5rem', width: '2rem', height: '2rem', color: '#fef08a' }} />
)}
P{position}
</Box>
<Box>
<Text size="3xl" weight="bold" block mb={1} style={{ color: position === 1 ? '#facc15' : isPodium ? '#d1d5db' : 'white' }}>
{position === 1 ? '🏆 VICTORY!' : position === 2 ? '🥈 Second Place' : position === 3 ? '🥉 Podium Finish' : `P${position} Finish`}
</Text>
<Stack direction="row" align="center" gap={3} className="text-sm text-gray-400">
<Text>Started P{startPosition}</Text>
<Box style={{ width: '0.25rem', height: '0.25rem', borderRadius: '9999px', backgroundColor: '#525252' }} />
<Text color={isClean ? 'text-performance-green' : ''}>
{incidents}x incidents {isClean && '✨'}
</Text>
</Stack>
</Box>
</Stack>
<Stack direction="row" gap={3} wrap>
{positionChange !== 0 && (
<Surface variant="muted" rounded="2xl" border padding={3} style={{ minWidth: '100px', textAlign: 'center', background: positionChange > 0 ? 'rgba(16, 185, 129, 0.1)' : 'rgba(239, 68, 68, 0.1)', borderColor: positionChange > 0 ? 'rgba(16, 185, 129, 0.3)' : 'rgba(239, 68, 68, 0.3)' }}>
<Stack align="center">
<Text size="2xl" weight="bold" style={{ color: positionChange > 0 ? '#10b981' : '#ef4444' }}>
{positionChange > 0 ? '↑' : '↓'}{Math.abs(positionChange)}
</Text>
<Text size="xs" color="text-gray-400">{positionChange > 0 ? 'Gained' : 'Lost'}</Text>
</Stack>
</Surface>
)}
{ratingChange !== undefined && (
<Surface variant="muted" rounded="2xl" border padding={3} style={{ minWidth: '100px', textAlign: 'center', background: ratingChange > 0 ? 'rgba(245, 158, 11, 0.1)' : 'rgba(239, 68, 68, 0.1)', borderColor: ratingChange > 0 ? 'rgba(245, 158, 11, 0.3)' : 'rgba(239, 68, 68, 0.3)' }}>
<Stack align="center">
<Text font="mono" size="2xl" weight="bold" style={{ color: ratingChange > 0 ? '#f59e0b' : '#ef4444' }}>
{animatedRatingChange > 0 ? '+' : ''}{animatedRatingChange}
</Text>
<Text size="xs" color="text-gray-400">Rating</Text>
</Stack>
</Surface>
)}
</Stack>
</Stack>
</Surface>
</Surface>
);
}