Files
gridpilot.gg/apps/website/components/mockups/CareerProgressionMockup.tsx
2026-01-18 23:24:30 +01:00

220 lines
10 KiB
TypeScript
Raw Permalink 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 { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { motion, useReducedMotion } from 'framer-motion';
import { useEffect, useState } from 'react';
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 (
<Stack position="relative" fullWidth fullHeight bg="graphite-black" rounded="none" p={4} overflow="hidden" display="flex" alignItems="center" justifyContent="center">
<Stack
as={motion.div}
initial="hidden"
animate="visible"
variants={{
visible: { transition: { staggerChildren: 0.1 } }
}}
w="full"
>
<Stack gap={4}>
{/* Clean stat cards */}
<Stack 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) => (
<Stack 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>
</Stack>
))}
</Stack>
{/* Single elegant season card */}
<Stack as={motion.div} variants={itemVariants}>
<Stack bg="panel-gray/40" rounded="none" p={3} border borderColor="border-gray/50">
<Stack display="flex" alignItems="center" justifyContent="between">
<Text size="sm" color="text-white" opacity={0.7} weight="bold">GT3 Championship</Text>
<Stack 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>
</Stack>
</Stack>
</Stack>
</Stack>
</Stack>
</Stack>
</Stack>
);
}
// Desktop version - more detailed
return (
<Stack position="relative" fullWidth fullHeight bg="graphite-black" rounded="none" p={{ base: 1.5, sm: 3, md: 5, lg: 8 }} overflow="hidden">
<Stack
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 */}
<Stack 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">
<Stack 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>
<Stack position="absolute" top="-1px" left="-1px" w="2" h="2" borderTop borderLeft borderColor="primary-accent" />
</Stack>
<Stack 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>
<Stack 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>
</Stack>
</Stack>
</Stack>
{/* Career Stats */}
<Stack 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>
<Stack 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) => (
<Stack
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>
</Stack>
))}
</Stack>
</Stack>
{/* Season Timeline */}
<Stack 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) => (
<Stack
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 }
}}
>
<Stack 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>
</Stack>
<Stack 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>
</Stack>
<Stack display="flex" gap={{ base: 1, sm: 1.5, md: 2 }}>
<Stack 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>
</Stack>
<Stack 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>
</Stack>
</Stack>
</Stack>
))}
</Stack>
</Stack>
{/* Multi-League Badge */}
<Stack as={motion.div} variants={itemVariants}>
<Stack 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">
<Stack display="flex"
// eslint-disable-next-line gridpilot-rules/component-classification
className="-space-x-2"
>
{[1, 2, 3].map((i) => (
<Stack 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>
</Stack>
))}
</Stack>
<Text size={{ base: 'xs', sm: 'sm' }} color="text-gray-400" weight="medium">Active in 3 leagues across seasons</Text>
</Stack>
</Stack>
</Stack>
</Stack>
</Stack>
);
}