website refactor
This commit is contained in:
@@ -20,11 +20,12 @@ import {
|
||||
} from 'lucide-react';
|
||||
import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel';
|
||||
import type { LeagueScoringPresetViewModel } from '@/lib/view-models/LeagueScoringPresetViewModel';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Heading } from '@/ui/Heading';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
import { Card } from '@/ui/Card';
|
||||
import { Grid } from '@/ui/Grid';
|
||||
|
||||
interface LeagueReviewSummaryProps {
|
||||
form: LeagueConfigFormModel;
|
||||
@@ -46,17 +47,17 @@ function ReviewCard({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Box rounded="xl" bg="bg-iron-gray/50" border borderColor="border-charcoal-outline/40" p={4}>
|
||||
<Card rounded="xl" className="bg-iron-gray/50 border-charcoal-outline/40" p={4}>
|
||||
<Stack gap={3}>
|
||||
<Box display="flex" alignItems="center" gap={3}>
|
||||
<Box display="flex" h="9" w="9" alignItems="center" justifyContent="center" rounded="lg" bg={bgColor}>
|
||||
<Stack direction="row" align="center" gap={3}>
|
||||
<Stack h="9" w="9" align="center" justify="center" rounded="lg" bg={bgColor}>
|
||||
<Icon icon={icon} size={4} color={iconColor} />
|
||||
</Box>
|
||||
</Stack>
|
||||
<Heading level={3} fontSize="sm" weight="semibold" color="text-white">{title}</Heading>
|
||||
</Box>
|
||||
</Stack>
|
||||
{children}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -73,21 +74,19 @@ function InfoRow({
|
||||
valueClass?: string;
|
||||
}) {
|
||||
return (
|
||||
<Box display="flex" alignItems="center" justifyContent="between" py={2} borderBottom borderColor="border-charcoal-outline/20"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
<Stack direction="row" align="center" justify="between" py={2} borderBottom borderColor="border-charcoal-outline/20"
|
||||
className="last:border-0"
|
||||
>
|
||||
<Box display="flex" alignItems="center" gap={2}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
{icon && <Icon icon={icon} size={3.5} color="text-gray-500" />}
|
||||
<Text size="xs" color="text-gray-500">{label}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
<Text size="sm" weight="medium" color="text-white"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className={valueClass}
|
||||
>
|
||||
{value}
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -186,34 +185,32 @@ export function LeagueReviewSummary({ form, presets }: LeagueReviewSummaryProps)
|
||||
{/* League Summary */}
|
||||
<Stack gap={3}>
|
||||
<Heading level={3} fontSize="sm" weight="semibold" color="text-gray-300">League summary</Heading>
|
||||
<Box position="relative" rounded="2xl" bg="bg-gradient-to-br from-primary-blue/20 via-iron-gray to-iron-gray" border borderColor="border-primary-blue/30" p={6} overflow="hidden">
|
||||
<Stack position="relative" rounded="2xl" bg="bg-gradient-to-br from-primary-blue/20 via-iron-gray to-iron-gray" border borderColor="border-primary-blue/30" p={6} overflow="hidden">
|
||||
{/* Background decoration */}
|
||||
<Box position="absolute" top="0" right="0" w="32" h="32" bg="bg-primary-blue/10" rounded="full"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
<Stack position="absolute" top={0} right={0} w="32" h="32" bg="bg-primary-blue/10" rounded="full"
|
||||
className="blur-3xl"
|
||||
/>
|
||||
<Box position="absolute" bottom="0" left="0" w="24" h="24" bg="bg-neon-aqua/5" rounded="full"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
>{null}</Stack>
|
||||
<Stack position="absolute" bottom="0" left="0" w="24" h="24" bg="bg-neon-aqua/5" rounded="full"
|
||||
className="blur-2xl"
|
||||
/>
|
||||
>{null}</Stack>
|
||||
|
||||
<Box position="relative" display="flex" alignItems="start" gap={4}>
|
||||
<Box display="flex" h="14" w="14" alignItems="center" justifyContent="center" rounded="2xl" bg="bg-primary-blue/20" border borderColor="border-primary-blue/30" flexShrink={0}>
|
||||
<Stack position="relative" direction="row" align="start" gap={4}>
|
||||
<Stack h="14" w="14" align="center" justify="center" rounded="2xl" bg="bg-primary-blue/20" border borderColor="border-primary-blue/30" flexShrink={0}>
|
||||
<Icon icon={Rocket} size={7} color="text-primary-blue" />
|
||||
</Box>
|
||||
<Box flexGrow={1} minWidth="0">
|
||||
</Stack>
|
||||
<Stack flexGrow={1} style={{ minWidth: 0 }}>
|
||||
<Heading level={2} fontSize="xl" weight="bold" color="text-white" mb={1} truncate>
|
||||
{basics.name || 'Your New League'}
|
||||
</Heading>
|
||||
<Text size="sm" color="text-gray-400" mb={3} block>
|
||||
{basics.description || 'Ready to launch your racing series!'}
|
||||
</Text>
|
||||
<Box display="flex" flexWrap="wrap" alignItems="center" gap={3}>
|
||||
<Stack direction="row" wrap align="center" gap={3}>
|
||||
{/* Ranked/Unranked Badge */}
|
||||
<Box
|
||||
<Stack
|
||||
as="span"
|
||||
display="inline-flex"
|
||||
alignItems="center"
|
||||
direction="row"
|
||||
align="center"
|
||||
gap={1.5}
|
||||
rounded="full"
|
||||
px={3}
|
||||
@@ -226,31 +223,30 @@ export function LeagueReviewSummary({ form, presets }: LeagueReviewSummaryProps)
|
||||
<Icon icon={isRanked ? Trophy : Users} size={3} />
|
||||
<Text weight="semibold" size="xs">{visibilityLabel}</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
opacity={0.7}
|
||||
>
|
||||
• {visibilityDescription}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box as="span" display="inline-flex" alignItems="center" gap={1.5} rounded="full" bg="bg-charcoal-outline/50" px={3} py={1} color="text-gray-300">
|
||||
</Stack>
|
||||
<Stack as="span" direction="row" align="center" gap={1.5} rounded="full" bg="bg-charcoal-outline/50" px={3} py={1} color="text-gray-300">
|
||||
<Icon icon={Gamepad2} size={3} />
|
||||
<Text size="xs" weight="medium">iRacing</Text>
|
||||
</Box>
|
||||
<Box as="span" display="inline-flex" alignItems="center" gap={1.5} rounded="full" bg="bg-charcoal-outline/50" px={3} py={1} color="text-gray-300">
|
||||
</Stack>
|
||||
<Stack as="span" direction="row" align="center" gap={1.5} rounded="full" bg="bg-charcoal-outline/50" px={3} py={1} color="text-gray-300">
|
||||
<Icon icon={structure.mode === 'solo' ? User : UsersRound} size={3} />
|
||||
<Text size="xs" weight="medium">{modeLabel}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
{/* Season Summary */}
|
||||
<Stack gap={3}>
|
||||
<Heading level={3} fontSize="sm" weight="semibold" color="text-gray-300">First season summary</Heading>
|
||||
<Box display="flex" flexWrap="wrap" alignItems="center" gap={2}>
|
||||
<Stack direction="row" wrap align="center" gap={2}>
|
||||
<Text size="xs" color="text-gray-400">{seasonName || 'First season of this league'}</Text>
|
||||
{seasonStartLabel && (
|
||||
<>
|
||||
@@ -266,51 +262,51 @@ export function LeagueReviewSummary({ form, presets }: LeagueReviewSummaryProps)
|
||||
)}
|
||||
<Text size="xs" color="text-gray-400">•</Text>
|
||||
<Text size="xs" color="text-gray-400">Stewarding: {stewardingLabel}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
{/* Stats Grid */}
|
||||
<Box display="grid" gridCols={{ base: 2, md: 4 }} gap={3}>
|
||||
<Grid cols={2} mdCols={4} gap={3}>
|
||||
{/* Capacity */}
|
||||
<Box rounded="xl" bg="bg-iron-gray/50" border borderColor="border-charcoal-outline/40" p={4} textAlign="center">
|
||||
<Box display="flex" h="10" w="10" alignItems="center" justifyContent="center" rounded="lg" bg="bg-primary-blue/10" mx="auto" mb={2}>
|
||||
<Card rounded="xl" className="bg-iron-gray/50 border-charcoal-outline/40 text-center" p={4}>
|
||||
<Stack h="10" w="10" align="center" justify="center" rounded="lg" bg="bg-primary-blue/10" mx="auto" mb={2}>
|
||||
<Icon icon={Users} size={5} color="text-primary-blue" />
|
||||
</Box>
|
||||
</Stack>
|
||||
<Text size="2xl" weight="bold" color="text-white" block>{capacityValue}</Text>
|
||||
<Text size="xs" color="text-gray-500" block>{capacityLabel}</Text>
|
||||
</Box>
|
||||
</Card>
|
||||
|
||||
{/* Rounds */}
|
||||
<Box rounded="xl" bg="bg-iron-gray/50" border borderColor="border-charcoal-outline/40" p={4} textAlign="center">
|
||||
<Box display="flex" h="10" w="10" alignItems="center" justifyContent="center" rounded="lg" bg="bg-performance-green/10" mx="auto" mb={2}>
|
||||
<Card rounded="xl" className="bg-iron-gray/50 border-charcoal-outline/40 text-center" p={4}>
|
||||
<Stack h="10" w="10" align="center" justify="center" rounded="lg" bg="bg-performance-green/10" mx="auto" mb={2}>
|
||||
<Icon icon={Flag} size={5} color="text-performance-green" />
|
||||
</Box>
|
||||
</Stack>
|
||||
<Text size="2xl" weight="bold" color="text-white" block>{timings.roundsPlanned ?? '—'}</Text>
|
||||
<Text size="xs" color="text-gray-500" block>rounds</Text>
|
||||
</Box>
|
||||
</Card>
|
||||
|
||||
{/* Weekend Duration */}
|
||||
<Box rounded="xl" bg="bg-iron-gray/50" border borderColor="border-charcoal-outline/40" p={4} textAlign="center">
|
||||
<Box display="flex" h="10" w="10" alignItems="center" justifyContent="center" rounded="lg" bg="bg-warning-amber/10" mx="auto" mb={2}>
|
||||
<Card rounded="xl" className="bg-iron-gray/50 border-charcoal-outline/40 text-center" p={4}>
|
||||
<Stack h="10" w="10" align="center" justify="center" rounded="lg" bg="bg-warning-amber/10" mx="auto" mb={2}>
|
||||
<Icon icon={Timer} size={5} color="text-warning-amber" />
|
||||
</Box>
|
||||
</Stack>
|
||||
<Text size="2xl" weight="bold" color="text-white" block>{totalWeekendMinutes > 0 ? `${totalWeekendMinutes}` : '—'}</Text>
|
||||
<Text size="xs" color="text-gray-500" block>min/weekend</Text>
|
||||
</Box>
|
||||
</Card>
|
||||
|
||||
{/* Championships */}
|
||||
<Box rounded="xl" bg="bg-iron-gray/50" border borderColor="border-charcoal-outline/40" p={4} textAlign="center">
|
||||
<Box display="flex" h="10" w="10" alignItems="center" justifyContent="center" rounded="lg" bg="bg-neon-aqua/10" mx="auto" mb={2}>
|
||||
<Card rounded="xl" className="bg-iron-gray/50 border-charcoal-outline/40 text-center" p={4}>
|
||||
<Stack h="10" w="10" align="center" justify="center" rounded="lg" bg="bg-neon-aqua/10" mx="auto" mb={2}>
|
||||
<Icon icon={Award} size={5} color="text-neon-aqua" />
|
||||
</Box>
|
||||
</Stack>
|
||||
<Text size="2xl" weight="bold" color="text-white" block>
|
||||
{[championships.enableDriverChampionship, championships.enableTeamChampionship, championships.enableNationsChampionship, championships.enableTrophyChampionship].filter(Boolean).length}
|
||||
</Text>
|
||||
<Text size="xs" color="text-gray-500" block>championships</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Stack>
|
||||
|
||||
{/* Detail Cards Grid */}
|
||||
<Box display="grid" gridCols={{ base: 1, md: 2 }} gap={4}>
|
||||
<Grid cols={1} mdCols={2} gap={4}>
|
||||
{/* Schedule Card */}
|
||||
<ReviewCard icon={Calendar} title="Race Weekend">
|
||||
<Stack gap={1}>
|
||||
@@ -329,91 +325,90 @@ export function LeagueReviewSummary({ form, presets }: LeagueReviewSummaryProps)
|
||||
<ReviewCard icon={Trophy} iconColor="text-warning-amber" bgColor="bg-warning-amber/10" title="Scoring System">
|
||||
<Stack gap={3}>
|
||||
{/* Scoring Preset */}
|
||||
<Box display="flex" alignItems="center" gap={3} p={3} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
|
||||
<Stack direction="row" align="center" gap={3} p={3} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
|
||||
<Text size="2xl">{getScoringEmoji()}</Text>
|
||||
<Box flexGrow={1} minWidth="0">
|
||||
<Stack flexGrow={1} style={{ minWidth: 0 }}>
|
||||
<Text size="sm" weight="medium" color="text-white" block>{preset?.name ?? 'Custom'}</Text>
|
||||
<Text size="xs" color="text-gray-500" block>{preset?.sessionSummary ?? 'Custom scoring enabled'}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
{scoring.customScoringEnabled && (
|
||||
<Box as="span" px={2} py={0.5} rounded="sm" bg="bg-primary-blue/20">
|
||||
<Stack as="span" px={2} py={0.5} rounded="sm" bg="bg-primary-blue/20">
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
weight="medium"
|
||||
color="text-primary-blue"
|
||||
>
|
||||
Custom
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
{/* Drop Rule */}
|
||||
<Box display="flex" alignItems="center" gap={3} p={3} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
|
||||
<Box display="flex" h="8" w="8" alignItems="center" justifyContent="center" rounded="lg" bg="bg-charcoal-outline/50">
|
||||
<Stack direction="row" align="center" gap={3} p={3} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
|
||||
<Stack h="8" w="8" align="center" justify="center" rounded="lg" bg="bg-charcoal-outline/50">
|
||||
<Text size="base">{dropRuleInfo.emoji}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} minWidth="0">
|
||||
</Stack>
|
||||
<Stack flexGrow={1} style={{ minWidth: 0 }}>
|
||||
<Text size="sm" weight="medium" color="text-white" block>{dropRuleInfo.label}</Text>
|
||||
<Text size="xs" color="text-gray-500" block>{dropRuleInfo.description}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</ReviewCard>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
||||
{/* Championships Section */}
|
||||
<ReviewCard icon={Award} iconColor="text-neon-aqua" bgColor="bg-neon-aqua/10" title="Active Championships">
|
||||
<Box display="flex" flexWrap="wrap" gap={2}>
|
||||
<Stack direction="row" wrap gap={2}>
|
||||
{championships.enableDriverChampionship && (
|
||||
<Box as="span" display="inline-flex" alignItems="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Stack as="span" direction="row" align="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Icon icon={Trophy} size={3.5} color="text-primary-blue" />
|
||||
<Text size="xs" weight="medium" color="text-primary-blue">Driver Championship</Text>
|
||||
<Icon icon={Check} size={3} color="text-performance-green" />
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
{championships.enableTeamChampionship && (
|
||||
<Box as="span" display="inline-flex" alignItems="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Stack as="span" direction="row" align="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Icon icon={Award} size={3.5} color="text-primary-blue" />
|
||||
<Text size="xs" weight="medium" color="text-primary-blue">Team Championship</Text>
|
||||
<Icon icon={Check} size={3} color="text-performance-green" />
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
{championships.enableNationsChampionship && (
|
||||
<Box as="span" display="inline-flex" alignItems="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Stack as="span" direction="row" align="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Icon icon={Globe} size={3.5} color="text-primary-blue" />
|
||||
<Text size="xs" weight="medium" color="text-primary-blue">Nations Cup</Text>
|
||||
<Icon icon={Check} size={3} color="text-performance-green" />
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
{championships.enableTrophyChampionship && (
|
||||
<Box as="span" display="inline-flex" alignItems="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Stack as="span" direction="row" align="center" gap={1.5} rounded="lg" bg="bg-primary-blue/10" border borderColor="border-primary-blue/20" px={3} py={2}>
|
||||
<Icon icon={Medal} size={3.5} color="text-primary-blue" />
|
||||
<Text size="xs" weight="medium" color="text-primary-blue">Trophy Championship</Text>
|
||||
<Icon icon={Check} size={3} color="text-performance-green" />
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
{![championships.enableDriverChampionship, championships.enableTeamChampionship, championships.enableNationsChampionship, championships.enableTrophyChampionship].some(Boolean) && (
|
||||
<Text size="sm" color="text-gray-500">No championships enabled</Text>
|
||||
)}
|
||||
</Box>
|
||||
</Stack>
|
||||
</ReviewCard>
|
||||
|
||||
{/* Ready to launch message */}
|
||||
<Box rounded="xl" bg="bg-performance-green/5" border borderColor="border-performance-green/20" p={4}>
|
||||
<Box display="flex" alignItems="center" gap={3}>
|
||||
<Box display="flex" h="10" w="10" alignItems="center" justifyContent="center" rounded="lg" bg="bg-performance-green/20">
|
||||
<Card rounded="xl" className="bg-performance-green/5 border-performance-green/20" p={4}>
|
||||
<Stack direction="row" align="center" gap={3}>
|
||||
<Stack h="10" w="10" align="center" justify="center" rounded="lg" bg="bg-performance-green/20">
|
||||
<Icon icon={Check} size={5} color="text-performance-green" />
|
||||
</Box>
|
||||
<Box>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Text size="sm" weight="medium" color="text-white" block>Ready to launch!</Text>
|
||||
<Text size="xs" color="text-gray-400" block>
|
||||
Click "Create League" to launch your racing series. You can modify all settings later.
|
||||
Click "Create League" to launch your racing series. You can modify all settings later.
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user