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

296 lines
10 KiB
TypeScript

'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 TeamCompetitionMockup() {
const shouldReduceMotion = useReducedMotion();
const [hoveredDriver, setHoveredDriver] = useState<number | null>(null);
const [hoveredTeam, setHoveredTeam] = useState<number | null>(null);
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
setIsMobile(window.innerWidth < 768);
}, []);
const teamColors = ['#198CFF', '#6FE37A', '#FFBE4D', '#4ED4E0', '#9333EA'];
if (isMobile) {
return (
<Box position="relative" fullWidth fullHeight bg="graphite-black" rounded="none" p={3} overflow="hidden">
<Stack gap={4}>
<Box>
<Text size="xs" weight="bold" color="text-gray-500" mb={3} block className="uppercase tracking-widest">Drivers</Text>
<Stack gap={1}>
{[1, 2, 3].map((i) => (
<Box
key={i}
position="relative"
display="flex"
alignItems="center"
gap={2}
bg="panel-gray/40"
rounded="none"
p={2}
border
borderColor="border-gray/20"
overflow="hidden"
>
<Box
position="absolute"
left="0"
top="0"
bottom="0"
w="0.5"
style={{ backgroundColor: teamColors[i-1] }}
/>
<Box
h="5"
w="5"
rounded="none"
display="flex"
alignItems="center"
justifyContent="center"
weight="bold"
style={{
fontSize: '10px',
borderColor: teamColors[i-1],
backgroundColor: `${teamColors[i-1]}10`,
borderWidth: '1px'
}}
>
<Text color="text-white" font="mono">{i}</Text>
</Box>
<Box flexGrow={1}>
<Box h="1.5" w="full" bg="white/10" rounded="none" />
</Box>
<Box h="3" w="10" bg="graphite-black" rounded="none" border borderColor="border-gray/30" />
</Box>
))}
</Stack>
</Box>
<Box h="px" bg="border-gray/30" />
<Box>
<Text size="xs" weight="bold" color="text-gray-500" mb={3} block className="uppercase tracking-widest">Constructors</Text>
<Stack gap={1}>
{[1, 2, 3].map((i) => (
<Box
key={i}
position="relative"
display="flex"
alignItems="center"
gap={2}
bg="panel-gray/40"
rounded="none"
p={2}
border
borderColor="border-gray/20"
overflow="hidden"
>
<Box
position="absolute"
left="0"
top="0"
bottom="0"
w="0.5"
style={{ backgroundColor: teamColors[i-1] }}
/>
<Box flexGrow={1}>
<Box h="1.5" w="full" bg="white/10" rounded="none" mb={1.5} />
<Box position="relative" h="1" bg="graphite-black" rounded="none" overflow="hidden">
<Box
position="absolute"
insetY="0"
left="0"
style={{ backgroundColor: teamColors[i-1], width: `${100 - (i-1) * 15}%` }}
/>
</Box>
</Box>
</Box>
))}
</Stack>
</Box>
</Stack>
</Box>
);
}
const leftColumnVariants = {
hidden: { opacity: 0, x: shouldReduceMotion ? 0 : -20 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.4 }
}
};
const rightColumnVariants = {
hidden: { opacity: 0, x: shouldReduceMotion ? 0 : 20 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.4 }
}
};
const rowVariants = {
hidden: { opacity: 0, x: shouldReduceMotion ? 0 : -10 },
visible: (i: number) => ({
opacity: 1,
x: 0,
transition: {
delay: shouldReduceMotion ? 0 : 0.3 + i * 0.05,
duration: 0.3
}
})
};
return (
<Box position="relative" fullWidth fullHeight bg="graphite-black" rounded="none" p={{ base: 1.5, sm: 3, md: 4, lg: 6 }} overflow="hidden">
<Box display="grid" gridCols={2} gap={{ base: 2, sm: 3, md: 4, lg: 6 }} fullHeight>
<Box
as={motion.div}
variants={leftColumnVariants}
initial="hidden"
animate="visible"
position="relative"
>
<Box h="6" w="24" bg="panel-gray" rounded="none" mb={4} display="flex" alignItems="center" justifyContent="center" border borderColor="border-gray/30">
<Text size="xs" color="text-gray-400" weight="bold" className="uppercase tracking-widest">DRIVERS</Text>
</Box>
<Stack gap={1}>
{[1, 2, 3, 4, 5].map((i) => (
<Box
key={i}
as={motion.div}
custom={i}
variants={rowVariants}
initial="hidden"
animate="visible"
position="relative"
display="flex"
alignItems="center"
gap={3}
bg="panel-gray/20"
rounded="none"
p={2}
border
borderColor="border-gray/20"
overflow="hidden"
onHoverStart={() => !shouldReduceMotion && setHoveredDriver(i)}
onHoverEnd={() => setHoveredDriver(null)}
whileHover={shouldReduceMotion ? {} : {
x: 4,
borderColor: `${teamColors[i-1]}40`,
transition: { duration: 0.15 }
}}
>
<Box
position="absolute"
left="0"
top="0"
bottom="0"
w="0.5"
style={{ backgroundColor: teamColors[i-1] }}
/>
<Box
h="5"
w="5"
rounded="none"
display="flex"
alignItems="center"
justifyContent="center"
weight="bold"
border
borderWidth="1px"
style={{
fontSize: '10px',
borderColor: teamColors[i-1],
backgroundColor: `${teamColors[i-1]}10`
}}
>
<Text color="text-white" font="mono">{i}</Text>
</Box>
<Box flexGrow={1} minWidth="0">
<Box h="1.5" w="full" bg="white/10" rounded="none" />
</Box>
<Box h="3" w="12" bg="graphite-black" rounded="none" border borderColor="border-gray/30" />
</Box>
))}
</Stack>
</Box>
<Box
as={motion.div}
variants={rightColumnVariants}
initial="hidden"
animate="visible"
position="relative"
>
<Box h="6" w="32" bg="panel-gray" rounded="none" mb={4} display="flex" alignItems="center" justifyContent="center" border borderColor="border-gray/30">
<Text size="xs" color="text-gray-400" weight="bold" className="uppercase tracking-widest">CONSTRUCTORS</Text>
</Box>
<Stack gap={1}>
{[1, 2, 3, 4, 5].map((i) => (
<Box
key={i}
as={motion.div}
custom={i}
variants={rowVariants}
initial="hidden"
animate="visible"
position="relative"
display="flex"
alignItems="center"
gap={3}
bg="panel-gray/20"
rounded="none"
p={2}
border
borderColor="border-gray/20"
overflow="hidden"
onHoverStart={() => !shouldReduceMotion && setHoveredTeam(i)}
onHoverEnd={() => setHoveredTeam(null)}
whileHover={shouldReduceMotion ? {} : {
x: -4,
borderColor: `${teamColors[i-1]}40`,
transition: { duration: 0.15 }
}}
>
<Box
position="absolute"
right="0"
top="0"
bottom="0"
w="0.5"
style={{ backgroundColor: teamColors[i-1] }}
/>
<Box flexGrow={1} minWidth="0">
<Box h="1.5" w="full" bg="white/10" rounded="none" mb={1.5} />
<Box position="relative" h="1" bg="graphite-black" rounded="none" overflow="hidden">
<Box
as={motion.div}
position="absolute"
insetY="0"
left="0"
style={{ backgroundColor: teamColors[i-1] }}
initial={{ width: '0%' }}
animate={{ width: `${100 - (i-1) * 15}%` }}
transition={{ duration: shouldReduceMotion ? 0 : 0.8, delay: 0.4 + i * 0.05 }}
/>
</Box>
</Box>
</Box>
))}
</Stack>
</Box>
</Box>
</Box>
);
}