website refactor

This commit is contained in:
2026-01-18 16:18:18 +01:00
parent 0b301feb61
commit 13567d51af
329 changed files with 4701 additions and 4750 deletions

View File

@@ -5,10 +5,9 @@ import { useState, useRef, useEffect, useMemo } from 'react';
import type * as React from 'react';
import { createPortal } from 'react-dom';
import { Input } from '@/ui/Input';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Heading } from '@/ui/Heading';
import { Stack } from '@/ui/Stack';
import { Icon } from '@/ui/Icon';
import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel';
@@ -85,7 +84,7 @@ function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutP
if (!isOpen || !mounted) return null;
return createPortal(
<Box
<Stack
ref={flyoutRef}
position="fixed"
zIndex={50}
@@ -98,7 +97,7 @@ function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutP
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ top: position.top, left: position.left, maxHeight: '80vh', overflowY: 'auto' }}
>
<Box
<Stack
display="flex"
alignItems="center"
justifyContent="between"
@@ -114,7 +113,7 @@ function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutP
<Icon icon={HelpCircle} size={4} color="text-primary-blue" />
<Text size="sm" weight="semibold" color="text-white">{title}</Text>
</Stack>
<Box
<Stack
as="button"
type="button"
onClick={onClose}
@@ -128,12 +127,12 @@ function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutP
hoverBg="bg-charcoal-outline"
>
<Icon icon={X} size={4} color="text-gray-400" />
</Box>
</Box>
<Box p={4}>
</Stack>
</Stack>
<Stack p={4}>
{children}
</Box>
</Box>,
</Stack>
</Stack>,
document.body
);
}
@@ -281,20 +280,20 @@ export function LeagueStructureSection({
return (
<Stack gap={8}>
{/* Emotional header */}
<Box textAlign="center" pb={2}>
<Stack textAlign="center" pb={2}>
<Heading level={3} mb={2}>
How will your drivers compete?
</Heading>
<Text size="sm" color="text-gray-400" maxWidth="lg" mx="auto" block>
Choose your championship format individual glory or team triumph.
</Text>
</Box>
</Stack>
{/* Mode Selection Cards */}
<Box display="grid" responsiveGridCols={{ base: 1, md: 2 }} gap={4}>
<Stack display="grid" responsiveGridCols={{ base: 1, md: 2 }} gap={4}>
{/* Solo Mode Card */}
<Box position="relative">
<Box
<Stack position="relative">
<Stack
as="button"
type="button"
disabled={disabled}
@@ -319,9 +318,9 @@ export function LeagueStructureSection({
group
>
{/* Header */}
<Box display="flex" alignItems="start" justifyContent="between">
<Stack display="flex" alignItems="start" justifyContent="between">
<Stack direction="row" align="center" gap={3}>
<Box
<Stack
display="flex"
h="12"
w="12"
@@ -331,18 +330,18 @@ export function LeagueStructureSection({
bg={isSolo ? 'bg-primary-blue/30' : 'bg-charcoal-outline/50'}
>
<Icon icon={User} size={6} color={isSolo ? 'text-primary-blue' : 'text-gray-400'} />
</Box>
<Box>
</Stack>
<Stack>
<Text weight="bold" size="lg" color={isSolo ? 'text-white' : 'text-gray-300'} block>
Solo Drivers
</Text>
<Text size="xs" color={isSolo ? 'text-primary-blue' : 'text-gray-500'} block>
Individual competition
</Text>
</Box>
</Stack>
</Stack>
{/* Radio indicator */}
<Box
<Stack
display="flex"
h="6"
w="6"
@@ -356,8 +355,8 @@ export function LeagueStructureSection({
transition
>
{isSolo && <Icon icon={Check} size={3.5} color="text-white" />}
</Box>
</Box>
</Stack>
</Stack>
{/* Emotional tagline */}
<Text size="sm" color={isSolo ? 'text-gray-300' : 'text-gray-500'} block>
@@ -379,10 +378,10 @@ export function LeagueStructureSection({
<Text size="xs" color="text-gray-400">Perfect for any grid size</Text>
</Stack>
</Stack>
</Box>
</Stack>
{/* Info button */}
<Box
<Stack
as="button"
ref={soloInfoRef}
type="button"
@@ -402,8 +401,8 @@ export function LeagueStructureSection({
hoverBg="bg-primary-blue/10"
>
<Icon icon={HelpCircle} size={4} />
</Box>
</Box>
</Stack>
</Stack>
{/* Solo Info Flyout */}
<InfoFlyout
@@ -445,8 +444,8 @@ export function LeagueStructureSection({
</InfoFlyout>
{/* Teams Mode Card */}
<Box position="relative">
<Box
<Stack position="relative">
<Stack
as="button"
type="button"
disabled={disabled}
@@ -471,9 +470,9 @@ export function LeagueStructureSection({
group
>
{/* Header */}
<Box display="flex" alignItems="start" justifyContent="between">
<Stack display="flex" alignItems="start" justifyContent="between">
<Stack direction="row" align="center" gap={3}>
<Box
<Stack
display="flex"
h="12"
w="12"
@@ -483,18 +482,18 @@ export function LeagueStructureSection({
bg={!isSolo ? 'bg-neon-aqua/30' : 'bg-charcoal-outline/50'}
>
<Icon icon={Users2} size={6} color={!isSolo ? 'text-neon-aqua' : 'text-gray-400'} />
</Box>
<Box>
</Stack>
<Stack>
<Text weight="bold" size="lg" color={!isSolo ? 'text-white' : 'text-gray-300'} block>
Team Racing
</Text>
<Text size="xs" color={!isSolo ? 'text-neon-aqua' : 'text-gray-500'} block>
Shared destiny
</Text>
</Box>
</Stack>
</Stack>
{/* Radio indicator */}
<Box
<Stack
display="flex"
h="6"
w="6"
@@ -508,8 +507,8 @@ export function LeagueStructureSection({
transition
>
{!isSolo && <Icon icon={Check} size={3.5} color="text-deep-graphite" />}
</Box>
</Box>
</Stack>
</Stack>
{/* Emotional tagline */}
<Text size="sm" color={!isSolo ? 'text-gray-300' : 'text-gray-500'} block>
@@ -531,10 +530,10 @@ export function LeagueStructureSection({
<Text size="xs" color="text-gray-400">Great for endurance & pro-am</Text>
</Stack>
</Stack>
</Box>
</Stack>
{/* Info button */}
<Box
<Stack
as="button"
ref={teamsInfoRef}
type="button"
@@ -554,8 +553,8 @@ export function LeagueStructureSection({
hoverBg="bg-neon-aqua/10"
>
<Icon icon={HelpCircle} size={4} />
</Box>
</Box>
</Stack>
</Stack>
{/* Teams Info Flyout */}
<InfoFlyout
@@ -595,13 +594,13 @@ export function LeagueStructureSection({
</Stack>
</Stack>
</InfoFlyout>
</Box>
</Stack>
{/* Configuration Panel */}
<Box rounded="xl" border borderColor="border-charcoal-outline" bg="bg-iron-gray/30" p={6}>
<Stack rounded="xl" border borderColor="border-charcoal-outline" bg="bg-iron-gray/30" p={6}>
<Stack gap={5}>
<Stack direction="row" align="center" gap={3}>
<Box
<Stack
display="flex"
h="10"
w="10"
@@ -615,8 +614,8 @@ export function LeagueStructureSection({
) : (
<Icon icon={Users2} size={5} color="text-neon-aqua" />
)}
</Box>
<Box>
</Stack>
<Stack>
<Text size="sm" weight="semibold" color="text-white" block>
{isSolo ? 'Grid size' : 'Team configuration'}
</Text>
@@ -626,7 +625,7 @@ export function LeagueStructureSection({
: 'Configure teams and roster sizes'
}
</Text>
</Box>
</Stack>
</Stack>
{/* Solo mode capacity */}
@@ -653,8 +652,8 @@ export function LeagueStructureSection({
<Stack gap={2}>
<Text size="xs" color="text-gray-500" block>Quick select:</Text>
<Box display="flex" flexWrap="wrap" gap={2}>
<Box
<Stack display="flex" flexWrap="wrap" gap={2}>
<Stack
as="button"
type="button"
onClick={() => handleMaxDriversChange('16')}
@@ -671,8 +670,8 @@ export function LeagueStructureSection({
transition
>
Compact (16)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => handleMaxDriversChange('24')}
@@ -689,8 +688,8 @@ export function LeagueStructureSection({
transition
>
Standard (24)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => handleMaxDriversChange('30')}
@@ -707,8 +706,8 @@ export function LeagueStructureSection({
transition
>
Full Grid (30)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => handleMaxDriversChange('40')}
@@ -725,8 +724,8 @@ export function LeagueStructureSection({
transition
>
Large (40)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => handleMaxDriversChange(String(gameConstraints.maxDrivers))}
@@ -743,8 +742,8 @@ export function LeagueStructureSection({
transition
>
Max ({gameConstraints.maxDrivers})
</Box>
</Box>
</Stack>
</Stack>
</Stack>
</Stack>
)}
@@ -755,8 +754,8 @@ export function LeagueStructureSection({
{/* Quick presets */}
<Stack gap={3}>
<Text size="xs" color="text-gray-500" block>Popular configurations:</Text>
<Box display="flex" flexWrap="wrap" gap={2}>
<Box
<Stack display="flex" flexWrap="wrap" gap={2}>
<Stack
as="button"
type="button"
onClick={() => {
@@ -776,8 +775,8 @@ export function LeagueStructureSection({
transition
>
10 × 2 (20 grid)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => {
@@ -797,8 +796,8 @@ export function LeagueStructureSection({
transition
>
12 × 2 (24 grid)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => {
@@ -818,8 +817,8 @@ export function LeagueStructureSection({
transition
>
8 × 3 (24 grid)
</Box>
<Box
</Stack>
<Stack
as="button"
type="button"
onClick={() => {
@@ -839,12 +838,12 @@ export function LeagueStructureSection({
transition
>
15 × 2 (30 grid)
</Box>
</Box>
</Stack>
</Stack>
</Stack>
{/* Manual configuration */}
<Box display="grid" responsiveGridCols={{ base: 1, sm: 3 }} gap={4} pt={2} borderTop borderColor="border-charcoal-outline/50">
<Stack display="grid" responsiveGridCols={{ base: 1, sm: 3 }} gap={4} pt={2} borderTop borderColor="border-charcoal-outline/50">
<Stack gap={2}>
<Text as="label" size="sm" weight="medium" color="text-gray-300" block>
Teams
@@ -877,7 +876,7 @@ export function LeagueStructureSection({
<Text as="label" size="sm" weight="medium" color="text-gray-300" block>
Total grid
</Text>
<Box
<Stack
display="flex"
alignItems="center"
justifyContent="center"
@@ -891,13 +890,13 @@ export function LeagueStructureSection({
{structure.maxDrivers ?? 0}
</Text>
<Text size="xs" color="text-gray-500" ml={1}>drivers</Text>
</Box>
</Stack>
</Stack>
</Box>
</Stack>
</Stack>
)}
</Stack>
</Box>
</Stack>
</Stack>
);
}