Files
gridpilot.gg/apps/website/components/mockups/CareerProgressionMockup.tsx
2026-01-15 17:12:24 +01:00

216 lines
10 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { motion, useReducedMotion } from 'framer-motion';
import { useState, useEffect } from 'react';
import { Box } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { Stack } from '@/ui/Stack';
export function CareerProgressionMockup() {
const shouldReduceMotion = useReducedMotion();
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkMobile = () => setIsMobile(window.innerWidth < 768);
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
const itemVariants = {
hidden: { opacity: 0, y: shouldReduceMotion ? 0 : 8 },
visible: { opacity: 1, y: 0 }
};
// Simple mobile version - just the essence
if (isMobile) {
return (
<Box position="relative" fullWidth fullHeight bg="bg-gradient-to-br from-deep-graphite to-iron-gray" rounded="lg" p={4} overflow="hidden" display="flex" alignItems="center" justifyContent="center">
<Box
as={motion.div}
initial="hidden"
animate="visible"
variants={{
visible: { transition: { staggerChildren: 0.1 } }
}}
w="full"
>
<Stack gap={4}>
{/* Clean stat cards */}
<Box as={motion.div} variants={itemVariants} display="grid" gridCols={3} gap={3}>
{[
{ value: '24', label: 'Wins' },
{ value: '48', label: 'Podiums' },
{ value: '156', label: 'Races' }
].map((stat, i) => (
<Box key={i} bg="bg-iron-gray/60" rounded="lg" p={3} border borderColor="border-primary-blue/20" textAlign="center">
<Text size="2xl" weight="bold" color="text-primary-blue" font="mono" block>{stat.value}</Text>
<Text
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ fontSize: '11px' }}
color="text-white"
opacity={0.5}
mt={1}
block
>
{stat.label}
</Text>
</Box>
))}
</Box>
{/* Single elegant season card */}
<Box as={motion.div} variants={itemVariants}>
<Box bg="bg-iron-gray/40" rounded="lg" p={3} border borderColor="border-charcoal-outline">
<Box display="flex" alignItems="center" justifyContent="between">
<Text size="sm" color="text-white" opacity={0.7}>GT3 Championship</Text>
<Box as="span" px={2.5} py={1} bg="bg-performance-green/20" rounded="sm">
<Text size="xs" color="text-performance-green" weight="semibold">P2</Text>
</Box>
</Box>
</Box>
</Box>
</Stack>
</Box>
</Box>
);
}
// Desktop version - more detailed
return (
<Box position="relative" fullWidth fullHeight bg="bg-gradient-to-br from-deep-graphite via-iron-gray to-deep-graphite" rounded="lg" p={{ base: 1.5, sm: 3, md: 5, lg: 8 }} overflow="hidden">
<Box
as={motion.div}
initial="hidden"
animate="visible"
variants={{
visible: { transition: { staggerChildren: shouldReduceMotion ? 0 : 0.08 } }
}}
>
<Stack gap={{ base: 1.5, sm: 3, md: 4, lg: 6 }}>
{/* Driver Header */}
<Box as={motion.div} variants={itemVariants} display="flex" alignItems="center" gap={{ base: 1.5, sm: 2, md: 3, lg: 4 }} pb={{ base: 1.5, sm: 3, md: 4, lg: 6 }} borderBottom borderColor="border-charcoal-outline">
<Box h={{ base: 8, sm: 10, md: 12, lg: 16 }} w={{ base: 8, sm: 10, md: 12, lg: 16 }} bg="bg-charcoal-outline" rounded="full" border borderWidth="2px" borderColor="border-primary-blue/30" display="flex" alignItems="center" justifyContent="center" overflow="hidden">
<Text size={{ base: 'base', sm: 'xl', md: '2xl', lg: '3xl' }}>🏎</Text>
</Box>
<Box flexGrow={1}>
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }} weight="semibold" color="text-white" opacity={0.9} mb={{ base: 1, sm: 1.5, md: 2 }} block>Your Racing Identity</Text>
<Box display="flex" alignItems="center" gap={{ base: 1, sm: 2, md: 3 }}>
<Text
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ fontSize: '10px' }}
color="text-primary-blue"
opacity={0.7}
>
Multi-league profile
</Text>
<Text
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ fontSize: '10px' }}
color="text-performance-green"
opacity={0.7}
>
Career tracking
</Text>
</Box>
</Box>
</Box>
{/* Career Stats */}
<Box as={motion.div} variants={itemVariants}>
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }} weight="semibold" color="text-white" opacity={0.6} mb={{ base: 1, sm: 2, md: 3 }} block>Career Overview</Text>
<Box display="grid" gridCols={3} gap={{ base: 1, sm: 2, md: 3 }}>
{[
{ label: 'Wins', value: '24' },
{ label: 'Podiums', value: '48' },
{ label: 'Races', value: '156' }
].map((stat, i) => (
<Box
key={i}
as={motion.div}
bg="bg-iron-gray"
rounded="lg"
p={{ base: 1, sm: 2, md: 3 }}
border
borderColor="border-charcoal-outline"
whileHover={shouldReduceMotion ? {} : {
y: -2,
boxShadow: '0 4px 16px rgba(0,0,0,0.3)',
transition: { duration: 0.15 }
}}
>
<Text size={{ base: 'sm', sm: 'base', md: 'lg' }} weight="bold" color="text-primary-blue" font="mono" mb={0.5} block>{stat.value}</Text>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-white" opacity={0.4} block>{stat.label}</Text>
</Box>
))}
</Box>
</Box>
{/* Season Timeline */}
<Box as={motion.div} variants={itemVariants}>
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }} weight="semibold" color="text-white" opacity={0.6} mb={{ base: 1, sm: 2, md: 3 }} block>Season History</Text>
<Stack gap={{ base: 1, sm: 1.5, md: 2 }}>
{[
{ league: 'GT3 Championship', season: 'S3', position: 'P2', points: '248' },
{ league: 'Endurance Series', season: 'S2', position: 'P1', points: '312' },
{ league: 'Formula Sprint', season: 'S1', position: 'P5', points: '186' }
].map((season, i) => (
<Box
key={i}
as={motion.div}
display="flex"
alignItems="center"
gap={{ base: 1.5, sm: 2, md: 3 }}
bg="bg-iron-gray"
rounded="lg"
p={{ base: 1.5, sm: 2, md: 3 }}
border
borderColor="border-charcoal-outline"
whileHover={shouldReduceMotion ? {} : {
x: 4,
boxShadow: '0 2px 12px rgba(25,140,255,0.2)',
transition: { duration: 0.15 }
}}
>
<Box h={{ base: 5, sm: 6, md: 8 }} w={{ base: 5, sm: 6, md: 8 }} bg="bg-charcoal-outline" rounded border borderColor="border-primary-blue/20" display="flex" alignItems="center" justifyContent="center">
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }}>🏁</Text>
</Box>
<Box flexGrow={1}>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-white" opacity={0.8} mb={{ base: 0.5, sm: 1 }} block>{season.league}</Text>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-white" opacity={0.4} block>Season complete</Text>
</Box>
<Box display="flex" gap={{ base: 1, sm: 1.5, md: 2 }}>
<Box as="span" px={{ base: 1, sm: 1.5, md: 2 }} py={0.5} bg="bg-performance-green/20" rounded="sm">
<Text size={{ base: 'xs', sm: 'sm' }} color="text-performance-green" weight="semibold">{season.position}</Text>
</Box>
<Box as="span" px={{ base: 1, sm: 1.5, md: 2 }} py={0.5} bg="bg-primary-blue/20" rounded="sm">
<Text size={{ base: 'xs', sm: 'sm' }} color="text-primary-blue" font="mono">{season.points}</Text>
</Box>
</Box>
</Box>
))}
</Stack>
</Box>
{/* Multi-League Badge */}
<Box as={motion.div} variants={itemVariants}>
<Box display="flex" alignItems="center" gap={{ base: 1, sm: 1.5, md: 2 }} bg="bg-charcoal-outline" rounded="lg" p={{ base: 1.5, sm: 2, md: 3 }} border borderColor="border-primary-blue/30">
<Box display="flex"
// eslint-disable-next-line gridpilot-rules/component-classification
className="-space-x-2"
>
{[1, 2, 3].map((i) => (
<Box key={i} h={{ base: 4, sm: 5, md: 6 }} w={{ base: 4, sm: 5, md: 6 }} bg="bg-iron-gray" rounded="full" border borderWidth="2px" borderColor="border-charcoal-outline" display="flex" alignItems="center" justifyContent="center">
<Text size={{ base: 'xs', sm: 'sm' }}>🏆</Text>
</Box>
))}
</Box>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-white" opacity={0.6}>Active in 3 leagues across seasons</Text>
</Box>
</Box>
</Stack>
</Box>
</Box>
);
}