Files
gridpilot.gg/apps/website/components/mockups/CareerProgressionMockup.tsx
2026-01-17 02:32:34 +01:00

221 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="graphite-black" rounded="none" 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="panel-gray/60" rounded="none" p={3} border borderColor="primary-accent/20" textAlign="center">
<Text size="2xl" weight="bold" color="text-primary-accent" 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
font="mono"
uppercase
>
{stat.label}
</Text>
</Box>
))}
</Box>
{/* Single elegant season card */}
<Box as={motion.div} variants={itemVariants}>
<Box bg="panel-gray/40" rounded="none" p={3} border borderColor="border-gray/50">
<Box display="flex" alignItems="center" justifyContent="between">
<Text size="sm" color="text-white" opacity={0.7} weight="bold">GT3 Championship</Text>
<Box as="span" px={2.5} py={1} bg="success-green/10" border borderColor="success-green/30">
<Text size="xs" color="text-success-green" weight="bold" font="mono">P2</Text>
</Box>
</Box>
</Box>
</Box>
</Stack>
</Box>
</Box>
);
}
// Desktop version - more detailed
return (
<Box position="relative" fullWidth fullHeight bg="graphite-black" rounded="none" 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-gray/50">
<Box h={{ base: 8, sm: 10, md: 12, lg: 16 }} w={{ base: 8, sm: 10, md: 12, lg: 16 }} bg="panel-gray" rounded="none" border borderWidth="1px" borderColor="primary-accent/30" display="flex" alignItems="center" justifyContent="center" overflow="hidden" className="relative">
<Text size={{ base: 'base', sm: 'xl', md: '2xl', lg: '3xl' }}>🏎</Text>
<Box position="absolute" top="-1px" left="-1px" w="2" h="2" borderTop borderLeft borderColor="primary-accent" />
</Box>
<Box flexGrow={1}>
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }} weight="bold" color="text-white" opacity={0.9} mb={{ base: 1, sm: 1.5, md: 2 }} block className="uppercase tracking-widest">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-accent"
weight="bold"
className="uppercase tracking-widest"
>
Multi-league profile
</Text>
<Text
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ fontSize: '10px' }}
color="text-success-green"
weight="bold"
className="uppercase tracking-widest"
>
Career tracking
</Text>
</Box>
</Box>
</Box>
{/* Career Stats */}
<Box as={motion.div} variants={itemVariants}>
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }} weight="bold" color="text-gray-500" mb={{ base: 1, sm: 2, md: 3 }} block className="uppercase tracking-[0.2em]">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="panel-gray/40"
rounded="none"
p={{ base: 1, sm: 2, md: 3 }}
border
borderColor="border-gray/50"
whileHover={shouldReduceMotion ? {} : {
y: -2,
borderColor: '#198CFF80',
transition: { duration: 0.15 }
}}
>
<Text size={{ base: 'sm', sm: 'base', md: 'lg' }} weight="bold" color="text-primary-accent" font="mono" mb={0.5} block>{stat.value}</Text>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-gray-500" weight="bold" className="uppercase tracking-widest" block>{stat.label}</Text>
</Box>
))}
</Box>
</Box>
{/* Season Timeline */}
<Box as={motion.div} variants={itemVariants}>
<Text size={{ base: 'xs', sm: 'sm', md: 'base' }} weight="bold" color="text-gray-500" mb={{ base: 1, sm: 2, md: 3 }} block className="uppercase tracking-[0.2em]">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="panel-gray/20"
rounded="none"
p={{ base: 1.5, sm: 2, md: 3 }}
border
borderColor="border-gray/30"
whileHover={shouldReduceMotion ? {} : {
x: 4,
borderColor: '#198CFF50',
transition: { duration: 0.15 }
}}
>
<Box h={{ base: 5, sm: 6, md: 8 }} w={{ base: 5, sm: 6, md: 8 }} bg="panel-gray" rounded="none" border borderColor="primary-accent/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" weight="bold" mb={{ base: 0.5, sm: 1 }} block>{season.league}</Text>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-gray-500" font="mono" uppercase 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="success-green/10" border borderColor="success-green/30">
<Text size={{ base: 'xs', sm: 'sm' }} color="text-success-green" weight="bold" font="mono">{season.position}</Text>
</Box>
<Box as="span" px={{ base: 1, sm: 1.5, md: 2 }} py={0.5} bg="primary-accent/10" border borderColor="primary-accent/30">
<Text size={{ base: 'xs', sm: 'sm' }} color="text-primary-accent" font="mono" weight="bold">{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="panel-gray/40" rounded="none" p={{ base: 1.5, sm: 2, md: 3 }} border borderColor="primary-accent/20">
<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="panel-gray" rounded="full" border borderWidth="2px" borderColor="border-gray" display="flex" alignItems="center" justifyContent="center">
<Text size={{ base: 'xs', sm: 'sm' }}>🏆</Text>
</Box>
))}
</Box>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-gray-400" weight="medium">Active in 3 leagues across seasons</Text>
</Box>
</Box>
</Stack>
</Box>
</Box>
);
}