website refactor
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { Trophy, Award, Check, Zap, Settings, Globe, Medal, Plus, Minus, RotateCcw, HelpCircle, X, LucideIcon } from 'lucide-react';
|
||||
import { Trophy, Award, Check, Zap, Settings, Globe, Medal, Plus, Minus, RotateCcw, HelpCircle, X } from 'lucide-react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import type { LeagueScoringPresetViewModel } from '@/lib/view-models/LeagueScoringPresetViewModel';
|
||||
import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel';
|
||||
import type { CustomPointsConfig } from '@/lib/view-models/ScoringConfigurationViewModel';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Heading } from '@/ui/Heading';
|
||||
import { Grid } from '@/ui/Grid';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
@@ -102,16 +102,18 @@ function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutP
|
||||
ref={flyoutRef}
|
||||
position="fixed"
|
||||
zIndex={50}
|
||||
width="380px"
|
||||
backgroundColor="iron-gray"
|
||||
w="380px"
|
||||
bg="bg-iron-gray"
|
||||
border
|
||||
borderColor="charcoal-outline"
|
||||
borderColor="border-charcoal-outline"
|
||||
rounded="xl"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="max-h-[80vh] overflow-y-auto shadow-2xl animate-fade-in"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ top: position.top, left: position.left }}
|
||||
>
|
||||
{/* Header */}
|
||||
<Box display="flex" align="center" justify="between" padding={4} border borderBottom borderColor="charcoal-outline" position="sticky" top={0} backgroundColor="iron-gray" zIndex={10}>
|
||||
<Box display="flex" alignItems="center" justifyContent="between" p={4} borderBottom borderColor="border-charcoal-outline" position="sticky" top="0" bg="bg-iron-gray" zIndex={10}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Icon icon={HelpCircle} size={4} color="text-primary-blue" />
|
||||
<Text size="sm" weight="semibold" color="text-white">{title}</Text>
|
||||
@@ -120,14 +122,14 @@ function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutP
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onClose}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-6 w-6 p-0"
|
||||
icon={<Icon icon={X} size={4} color="text-gray-400" />}
|
||||
>
|
||||
{null}
|
||||
<Icon icon={X} size={4} color="text-gray-400" />
|
||||
</Button>
|
||||
</Box>
|
||||
{/* Content */}
|
||||
<Box padding={4}>
|
||||
<Box p={4}>
|
||||
{children}
|
||||
</Box>
|
||||
</Box>,
|
||||
@@ -142,10 +144,10 @@ function InfoButton({ onClick, buttonRef }: { onClick: () => void; buttonRef: Re
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onClick}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-5 w-5 p-0 rounded-full text-gray-500 hover:text-primary-blue hover:bg-primary-blue/10"
|
||||
icon={<Icon icon={HelpCircle} size={3.5} />}
|
||||
>
|
||||
{null}
|
||||
<Icon icon={HelpCircle} size={3.5} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -164,32 +166,64 @@ function PointsSystemMockup() {
|
||||
];
|
||||
|
||||
return (
|
||||
<Surface variant="dark" rounded="lg" padding={4}>
|
||||
<Surface variant="dark" rounded="lg" p={4}>
|
||||
<Stack gap={3}>
|
||||
<Box display="flex" align="center" justify="between" className="text-[10px] text-gray-500 uppercase tracking-wide px-1">
|
||||
<Text>Position</Text>
|
||||
<Text>Points</Text>
|
||||
<Box display="flex" alignItems="center" justifyContent="between" px={1}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Position
|
||||
</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Points
|
||||
</Text>
|
||||
</Box>
|
||||
{positions.map((p) => (
|
||||
<Stack key={p.pos} direction="row" align="center" gap={3}>
|
||||
<Box width={8} height={8} rounded="lg" className={p.color} display="flex" center>
|
||||
<Text size="sm" weight="bold" className={p.pos <= 3 ? 'text-deep-graphite' : 'text-gray-400'}>P{p.pos}</Text>
|
||||
<Box w="8" h="8" rounded="lg" bg={p.color} display="flex" alignItems="center" justifyContent="center">
|
||||
<Text size="sm" weight="bold" color={p.pos <= 3 ? 'text-deep-graphite' : 'text-gray-400'}>P{p.pos}</Text>
|
||||
</Box>
|
||||
<Box flex={1} height={2} backgroundColor="charcoal-outline" rounded="full" className="overflow-hidden opacity-50">
|
||||
<Box flexGrow={1} h="2" bg="bg-charcoal-outline" rounded="full" overflow="hidden" opacity={0.5}>
|
||||
<Box
|
||||
height="full"
|
||||
className="bg-gradient-to-r from-primary-blue to-neon-aqua rounded-full"
|
||||
h="full"
|
||||
bg="bg-gradient-to-r from-primary-blue to-neon-aqua"
|
||||
rounded="full"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ width: `${(p.pts / 25) * 100}%` }}
|
||||
/>
|
||||
</Box>
|
||||
<Box width={8} textAlign="right">
|
||||
<Box w="8" textAlign="right">
|
||||
<Text size="sm" font="mono" weight="semibold" color="text-white">{p.pts}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
))}
|
||||
<Box display="flex" align="center" justify="center" gap={1} pt={2} className="text-[10px] text-gray-500">
|
||||
<Text>...</Text>
|
||||
<Text>down to P10 = 1 point</Text>
|
||||
<Box display="flex" alignItems="center" justifyContent="center" gap={1} pt={2}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
>
|
||||
...
|
||||
</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
>
|
||||
down to P10 = 1 point
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Surface>
|
||||
@@ -204,15 +238,22 @@ function BonusPointsMockup() {
|
||||
];
|
||||
|
||||
return (
|
||||
<Surface variant="dark" rounded="lg" padding={4}>
|
||||
<Surface variant="dark" rounded="lg" p={4}>
|
||||
<Stack gap={2}>
|
||||
{bonuses.map((b, i) => (
|
||||
<Surface key={i} variant="muted" border rounded="lg" padding={2}>
|
||||
<Surface key={i} variant="muted" border rounded="lg" p={2}>
|
||||
<Stack direction="row" align="center" gap={3}>
|
||||
<Text size="xl">{b.emoji}</Text>
|
||||
<Box flex={1}>
|
||||
<Box flexGrow={1}>
|
||||
<Text size="xs" weight="medium" color="text-white" block>{b.label}</Text>
|
||||
<Text className="text-[10px] text-gray-500" block>{b.desc}</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
block
|
||||
>
|
||||
{b.desc}
|
||||
</Text>
|
||||
</Box>
|
||||
<Text size="sm" font="mono" weight="semibold" color="text-performance-green">{b.pts}</Text>
|
||||
</Stack>
|
||||
@@ -231,80 +272,48 @@ function ChampionshipMockup() {
|
||||
];
|
||||
|
||||
return (
|
||||
<Surface variant="dark" rounded="lg" padding={4}>
|
||||
<Box display="flex" align="center" gap={2} mb={3} pb={2} border borderBottom borderColor="charcoal-outline" className="opacity-50">
|
||||
<Surface variant="dark" rounded="lg" p={4}>
|
||||
<Box display="flex" alignItems="center" gap={2} mb={3} pb={2} borderBottom borderColor="border-charcoal-outline" opacity={0.5}>
|
||||
<Icon icon={Trophy} size={4} color="text-yellow-500" />
|
||||
<Text size="xs" weight="semibold" color="text-white">Driver Championship</Text>
|
||||
</Box>
|
||||
<Stack gap={2}>
|
||||
{standings.map((s) => (
|
||||
<Stack key={s.pos} direction="row" align="center" gap={2}>
|
||||
<Box width={6} height={6} rounded="full" display="flex" center className={s.pos === 1 ? 'bg-yellow-500 text-deep-graphite' : 'bg-charcoal-outline text-gray-400'}>
|
||||
<Text className="text-[10px]" weight="bold">{s.pos}</Text>
|
||||
<Box w="6" h="6" rounded="full" display="flex" alignItems="center" justifyContent="center" bg={s.pos === 1 ? 'bg-yellow-500' : 'bg-charcoal-outline'} color={s.pos === 1 ? 'text-deep-graphite' : 'text-gray-400'}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
weight="bold"
|
||||
>
|
||||
{s.pos}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box flex={1}>
|
||||
<Text size="xs" color="text-white" className="truncate" block>{s.name}</Text>
|
||||
<Box flexGrow={1}>
|
||||
<Text size="xs" color="text-white" truncate block>{s.name}</Text>
|
||||
</Box>
|
||||
<Text size="xs" font="mono" weight="semibold" color="text-white">{s.pts}</Text>
|
||||
{s.delta && (
|
||||
<Text className="text-[10px] font-mono text-gray-500">{s.delta}</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
font="mono"
|
||||
color="text-gray-500"
|
||||
>
|
||||
{s.delta}
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
))}
|
||||
</Stack>
|
||||
<Box mt={3} pt={2} border borderTop borderColor="charcoal-outline" className="text-[10px] text-gray-500 opacity-50" textAlign="center">
|
||||
<Text>Points accumulated across all races</Text>
|
||||
</Box>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
|
||||
function DropRulesMockup() {
|
||||
const results = [
|
||||
{ round: 'R1', pts: 25, dropped: false },
|
||||
{ round: 'R2', pts: 18, dropped: false },
|
||||
{ round: 'R3', pts: 4, dropped: true },
|
||||
{ round: 'R4', pts: 15, dropped: false },
|
||||
{ round: 'R5', pts: 12, dropped: false },
|
||||
{ round: 'R6', pts: 0, dropped: true },
|
||||
];
|
||||
|
||||
const total = results.filter(r => !r.dropped).reduce((sum, r) => sum + r.pts, 0);
|
||||
const wouldBe = results.reduce((sum, r) => sum + r.pts, 0);
|
||||
|
||||
return (
|
||||
<Surface variant="dark" rounded="lg" padding={4}>
|
||||
<Box mb={3} pb={2} border borderBottom borderColor="charcoal-outline" className="opacity-50">
|
||||
<Text size="xs" weight="semibold" color="text-white">Best 4 of 6 Results</Text>
|
||||
</Box>
|
||||
<Stack direction="row" gap={1} mb={3}>
|
||||
{results.map((r, i) => (
|
||||
<Box
|
||||
key={i}
|
||||
flex={1}
|
||||
padding={2}
|
||||
rounded="lg"
|
||||
textAlign="center"
|
||||
border
|
||||
borderColor={r.dropped ? 'charcoal-outline' : 'performance-green'}
|
||||
backgroundColor={r.dropped ? 'transparent' : 'performance-green'}
|
||||
opacity={r.dropped ? 0.5 : 0.1}
|
||||
className="transition-all"
|
||||
>
|
||||
<Text className="text-[9px] text-gray-500" block>{r.round}</Text>
|
||||
<Text size="xs" font="mono" weight="semibold" color={r.dropped ? 'text-gray-500' : 'text-white'} className={r.dropped ? 'line-through' : ''} block>
|
||||
{r.pts}
|
||||
</Text>
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
<Box display="flex" justify="between" align="center">
|
||||
<Text size="xs" color="text-gray-500">Total counted:</Text>
|
||||
<Text font="mono" weight="semibold" color="text-performance-green">{total} pts</Text>
|
||||
</Box>
|
||||
<Box display="flex" justify="between" align="center" mt={1} className="text-[10px] text-gray-500">
|
||||
<Text>Without drops:</Text>
|
||||
<Text font="mono">{wouldBe} pts</Text>
|
||||
<Box mt={3} pt={2} borderTop borderColor="border-charcoal-outline" opacity={0.5} textAlign="center">
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
>
|
||||
Points accumulated across all races
|
||||
</Text>
|
||||
</Box>
|
||||
</Surface>
|
||||
);
|
||||
@@ -418,7 +427,10 @@ export function LeagueScoringSection({
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid cols={2} gap={6} className="lg:grid-cols-[minmax(0,2fr)_minmax(0,1.4fr)]">
|
||||
<Grid cols={2} gap={6}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="lg:grid-cols-[minmax(0,2fr)_minmax(0,1.4fr)]"
|
||||
>
|
||||
{patternPanel}
|
||||
{championshipsPanel}
|
||||
</Grid>
|
||||
@@ -560,10 +572,10 @@ export function ScoringPatternSection({
|
||||
<Stack gap={5}>
|
||||
{/* Section header */}
|
||||
<Stack direction="row" align="center" gap={3}>
|
||||
<Box width={10} height={10} display="flex" center rounded="xl" backgroundColor="primary-blue" opacity={0.1}>
|
||||
<Box w="10" h="10" display="flex" alignItems="center" justifyContent="center" rounded="xl" bg="bg-primary-blue" opacity={0.1}>
|
||||
<Icon icon={Trophy} size={5} color="text-primary-blue" />
|
||||
</Box>
|
||||
<Box flex={1}>
|
||||
<Box flexGrow={1}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Heading level={3}>Points System</Heading>
|
||||
<InfoButton buttonRef={pointsInfoRef} onClick={() => setShowPointsFlyout(true)} />
|
||||
@@ -586,16 +598,32 @@ export function ScoringPatternSection({
|
||||
</Text>
|
||||
|
||||
<Box>
|
||||
<Box mb={2} className="text-[10px] text-gray-500 uppercase tracking-wide">
|
||||
<Text>Example: F1-Style Points</Text>
|
||||
<Box mb={2}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Example: F1-Style Points
|
||||
</Text>
|
||||
</Box>
|
||||
<PointsSystemMockup />
|
||||
</Box>
|
||||
|
||||
<Surface variant="muted" border rounded="lg" padding={3}>
|
||||
<Surface variant="muted" border rounded="lg" p={3}>
|
||||
<Stack direction="row" align="start" gap={2}>
|
||||
<Icon icon={Zap} size={3.5} color="text-primary-blue" className="mt-0.5" />
|
||||
<Text className="text-[11px] text-gray-400">
|
||||
<Icon icon={Zap} size={3.5} color="text-primary-blue"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '11px' }}
|
||||
color="text-gray-400"
|
||||
>
|
||||
<Text weight="medium" color="text-primary-blue">Pro tip:</Text> Sprint formats
|
||||
award points in both races, typically with reduced points for the sprint.
|
||||
</Text>
|
||||
@@ -605,11 +633,14 @@ export function ScoringPatternSection({
|
||||
</InfoFlyout>
|
||||
|
||||
{/* Two-column layout: Presets | Custom */}
|
||||
<Grid cols={2} gap={4} className="lg:grid-cols-[1fr_auto]">
|
||||
<Grid cols={2} gap={4}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="lg:grid-cols-[1fr_auto]"
|
||||
>
|
||||
{/* Preset options */}
|
||||
<Stack gap={2}>
|
||||
{presets.length === 0 ? (
|
||||
<Box padding={4} border borderStyle="dashed" borderColor="charcoal-outline" rounded="lg">
|
||||
<Box p={4} border borderStyle="dashed" borderColor="border-charcoal-outline" rounded="lg">
|
||||
<Text size="sm" color="text-gray-400">Loading presets...</Text>
|
||||
</Box>
|
||||
) : (
|
||||
@@ -622,6 +653,7 @@ export function ScoringPatternSection({
|
||||
variant="ghost"
|
||||
onClick={() => onChangePatternId?.(preset.id)}
|
||||
disabled={disabled}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className={`
|
||||
w-full flex items-center gap-3 p-3 rounded-xl border-2 text-left transition-all duration-200 h-auto
|
||||
${isSelected
|
||||
@@ -632,15 +664,17 @@ export function ScoringPatternSection({
|
||||
>
|
||||
{/* Radio indicator */}
|
||||
<Box
|
||||
width={5}
|
||||
height={5}
|
||||
w="5"
|
||||
h="5"
|
||||
display="flex"
|
||||
center
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
rounded="full"
|
||||
border
|
||||
borderColor={isSelected ? 'primary-blue' : 'gray-500'}
|
||||
backgroundColor={isSelected ? 'primary-blue' : 'transparent'}
|
||||
className="shrink-0 transition-colors"
|
||||
borderColor={isSelected ? 'border-primary-blue' : 'border-gray-500'}
|
||||
bg={isSelected ? 'bg-primary-blue' : 'transparent'}
|
||||
transition
|
||||
flexShrink={0}
|
||||
>
|
||||
{isSelected && <Icon icon={Check} size={3} color="text-white" />}
|
||||
</Box>
|
||||
@@ -649,14 +683,20 @@ export function ScoringPatternSection({
|
||||
<Text size="xl">{getPresetEmoji(preset)}</Text>
|
||||
|
||||
{/* Text */}
|
||||
<Box flex={1} className="min-w-0">
|
||||
<Box flexGrow={1}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="min-w-0"
|
||||
>
|
||||
<Text size="sm" weight="medium" color="text-white" block>{preset.name}</Text>
|
||||
<Text size="xs" color="text-gray-500" block>{getPresetDescription(preset)}</Text>
|
||||
</Box>
|
||||
|
||||
{/* Bonus badge */}
|
||||
{preset.bonusSummary && (
|
||||
<Box className="hidden sm:inline-flex items-center gap-1 px-2 py-1 rounded-full bg-charcoal-outline/30 text-[10px] text-gray-400">
|
||||
<Box
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="hidden sm:inline-flex items-center gap-1 px-2 py-1 rounded-full bg-charcoal-outline/30 text-[10px] text-gray-400"
|
||||
>
|
||||
<Icon icon={Zap} size={3} />
|
||||
<Text>{preset.bonusSummary}</Text>
|
||||
</Box>
|
||||
@@ -664,7 +704,7 @@ export function ScoringPatternSection({
|
||||
|
||||
{/* Info button */}
|
||||
<Box
|
||||
ref={(el: any) => { presetInfoRefs.current[preset.id] = el; }}
|
||||
ref={(el: HTMLElement | null) => { presetInfoRefs.current[preset.id] = el; }}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={(e: React.MouseEvent) => {
|
||||
@@ -678,7 +718,17 @@ export function ScoringPatternSection({
|
||||
setActivePresetFlyout(activePresetFlyout === preset.id ? null : preset.id);
|
||||
}
|
||||
}}
|
||||
className="flex h-6 w-6 items-center justify-center rounded-full text-gray-500 hover:text-primary-blue hover:bg-primary-blue/10 transition-colors shrink-0"
|
||||
display="flex"
|
||||
h="6"
|
||||
w="6"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
rounded="full"
|
||||
color="text-gray-500"
|
||||
hoverTextColor="text-primary-blue"
|
||||
hoverBg="bg-primary-blue/10"
|
||||
transition
|
||||
flexShrink={0}
|
||||
>
|
||||
<Icon icon={HelpCircle} size={3.5} />
|
||||
</Box>
|
||||
@@ -695,13 +745,28 @@ export function ScoringPatternSection({
|
||||
<Text size="xs" color="text-gray-400">{presetInfo.description}</Text>
|
||||
|
||||
<Stack gap={2}>
|
||||
<Box className="text-[10px] text-gray-500 uppercase tracking-wide">
|
||||
<Text>Key Features</Text>
|
||||
<Box>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Key Features
|
||||
</Text>
|
||||
</Box>
|
||||
<Box as="ul" className="space-y-1.5">
|
||||
<Box as="ul"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="space-y-1.5"
|
||||
>
|
||||
{presetInfo.details.map((detail, idx) => (
|
||||
<Box as="li" key={idx} display="flex" align="start" gap={2}>
|
||||
<Icon icon={Check} size={3} color="text-performance-green" className="mt-0.5" />
|
||||
<Box as="li" key={idx} display="flex" alignItems="start" gap={2}>
|
||||
<Icon icon={Check} size={3} color="text-performance-green"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<Text size="xs" color="text-gray-400">{detail}</Text>
|
||||
</Box>
|
||||
))}
|
||||
@@ -709,10 +774,17 @@ export function ScoringPatternSection({
|
||||
</Stack>
|
||||
|
||||
{preset.bonusSummary && (
|
||||
<Surface variant="muted" border rounded="lg" padding={3}>
|
||||
<Surface variant="muted" border rounded="lg" p={3}>
|
||||
<Stack direction="row" align="start" gap={2}>
|
||||
<Icon icon={Zap} size={3.5} color="text-primary-blue" className="mt-0.5" />
|
||||
<Text className="text-[11px] text-gray-400">
|
||||
<Icon icon={Zap} size={3.5} color="text-primary-blue"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '11px' }}
|
||||
color="text-gray-400"
|
||||
>
|
||||
<Text weight="medium" color="text-primary-blue">Bonus points:</Text> {preset.bonusSummary}
|
||||
</Text>
|
||||
</Stack>
|
||||
@@ -727,11 +799,15 @@ export function ScoringPatternSection({
|
||||
</Stack>
|
||||
|
||||
{/* Custom scoring option */}
|
||||
<Box width="full" className="lg:w-48">
|
||||
<Box w="full"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="lg:w-48"
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onToggleCustomScoring}
|
||||
disabled={!onToggleCustomScoring || readOnly}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className={`
|
||||
w-full h-full min-h-[100px] flex flex-col items-center justify-center gap-2 p-4 rounded-xl border-2 transition-all duration-200
|
||||
${isCustom
|
||||
@@ -741,25 +817,40 @@ export function ScoringPatternSection({
|
||||
`}
|
||||
>
|
||||
<Box
|
||||
width={10}
|
||||
height={10}
|
||||
w="10"
|
||||
h="10"
|
||||
display="flex"
|
||||
center
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
rounded="xl"
|
||||
backgroundColor={isCustom ? 'primary-blue' : 'charcoal-outline'}
|
||||
bg={isCustom ? 'bg-primary-blue' : 'bg-charcoal-outline'}
|
||||
opacity={isCustom ? 0.2 : 0.3}
|
||||
className="transition-colors"
|
||||
transition
|
||||
>
|
||||
<Icon icon={Settings} size={5} color={isCustom ? 'text-primary-blue' : 'text-gray-500'} />
|
||||
</Box>
|
||||
<Box textAlign="center">
|
||||
<Text size="sm" weight="medium" color={isCustom ? 'text-white' : 'text-gray-400'} block>Custom</Text>
|
||||
<Text className="text-[10px] text-gray-500" block>Define your own</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
block
|
||||
>
|
||||
Define your own
|
||||
</Text>
|
||||
</Box>
|
||||
{isCustom && (
|
||||
<Box display="flex" align="center" gap={1} px={2} py={0.5} rounded="full" backgroundColor="primary-blue" opacity={0.2}>
|
||||
<Box display="flex" alignItems="center" gap={1} px={2} py={0.5} rounded="full" bg="bg-primary-blue" opacity={0.2}>
|
||||
<Icon icon={Check} size={2.5} color="text-primary-blue" />
|
||||
<Text className="text-[10px]" weight="medium" color="text-primary-blue">Active</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
weight="medium"
|
||||
color="text-primary-blue"
|
||||
>
|
||||
Active
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Button>
|
||||
@@ -773,10 +864,10 @@ export function ScoringPatternSection({
|
||||
|
||||
{/* Custom scoring editor - inline, no placeholder */}
|
||||
{isCustom && (
|
||||
<Surface variant="muted" border rounded="xl" padding={4}>
|
||||
<Surface variant="muted" border rounded="xl" p={4}>
|
||||
<Stack gap={4}>
|
||||
{/* Header with reset button */}
|
||||
<Box display="flex" align="center" justify="between">
|
||||
<Box display="flex" alignItems="center" justifyContent="between">
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Icon icon={Settings} size={4} color="text-primary-blue" />
|
||||
<Text size="sm" weight="medium" color="text-white">Custom Points Table</Text>
|
||||
@@ -797,16 +888,32 @@ export function ScoringPatternSection({
|
||||
</Text>
|
||||
|
||||
<Box>
|
||||
<Box mb={2} className="text-[10px] text-gray-500 uppercase tracking-wide">
|
||||
<Text>Available Bonuses</Text>
|
||||
<Box mb={2}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Available Bonuses
|
||||
</Text>
|
||||
</Box>
|
||||
<BonusPointsMockup />
|
||||
</Box>
|
||||
|
||||
<Surface variant="muted" border rounded="lg" padding={3}>
|
||||
<Surface variant="muted" border rounded="lg" p={3}>
|
||||
<Stack direction="row" align="start" gap={2}>
|
||||
<Icon icon={Zap} size={3.5} color="text-primary-blue" className="mt-0.5" />
|
||||
<Text className="text-[11px] text-gray-400">
|
||||
<Icon icon={Zap} size={3.5} color="text-primary-blue"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '11px' }}
|
||||
color="text-gray-400"
|
||||
>
|
||||
<Text weight="medium" color="text-primary-blue">Example:</Text> A driver finishing
|
||||
P1 with pole and fastest lap would earn 25 + 1 + 1 = 27 points.
|
||||
</Text>
|
||||
@@ -820,16 +927,19 @@ export function ScoringPatternSection({
|
||||
size="sm"
|
||||
onClick={resetToDefaults}
|
||||
disabled={readOnly}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-auto py-1 px-2 text-[10px] text-gray-400 hover:text-primary-blue hover:bg-primary-blue/10"
|
||||
icon={<Icon icon={RotateCcw} size={3} />}
|
||||
>
|
||||
Reset
|
||||
<Stack direction="row" align="center" gap={1}>
|
||||
<Icon icon={RotateCcw} size={3} />
|
||||
<Text>Reset</Text>
|
||||
</Stack>
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* Race position points */}
|
||||
<Stack gap={2}>
|
||||
<Box display="flex" align="center" justify="between">
|
||||
<Box display="flex" alignItems="center" justifyContent="between">
|
||||
<Text size="xs" color="text-gray-400">Finish position points</Text>
|
||||
<Stack direction="row" align="center" gap={1}>
|
||||
<Button
|
||||
@@ -837,54 +947,70 @@ export function ScoringPatternSection({
|
||||
size="sm"
|
||||
onClick={removePosition}
|
||||
disabled={readOnly || customPoints.racePoints.length <= 3}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-5 w-5 p-0"
|
||||
icon={<Icon icon={Minus} size={3} />}
|
||||
>
|
||||
{null}
|
||||
<Icon icon={Minus} size={3} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={addPosition}
|
||||
disabled={readOnly || customPoints.racePoints.length >= 20}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-5 w-5 p-0"
|
||||
icon={<Icon icon={Plus} size={3} />}
|
||||
>
|
||||
{null}
|
||||
<Icon icon={Plus} size={3} />
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
<Stack direction="row" wrap gap={1}>
|
||||
<Box display="flex" flexWrap="wrap" gap={1}>
|
||||
{customPoints.racePoints.map((pts, idx) => (
|
||||
<Stack key={idx} align="center">
|
||||
<Text className="text-[9px] text-gray-500" mb={0.5}>P{idx + 1}</Text>
|
||||
<Stack direction="row" align="center" gap={0.5}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '9px' }}
|
||||
color="text-gray-500"
|
||||
mb={0.5}
|
||||
>
|
||||
P{idx + 1}
|
||||
</Text>
|
||||
<Box display="flex" alignItems="center">
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => updateRacePoints(idx, -1)}
|
||||
disabled={readOnly || pts <= 0}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-5 w-4 p-0 rounded-r-none text-[10px]"
|
||||
>
|
||||
−
|
||||
</Button>
|
||||
<Box width={6} height={5} display="flex" center backgroundColor="deep-graphite" border borderTop borderBottom borderColor="charcoal-outline">
|
||||
<Text className="text-[10px]" weight="medium" color="text-white">{pts}</Text>
|
||||
<Box w="6" h="5" display="flex" alignItems="center" justifyContent="center" bg="bg-deep-graphite" border borderTop borderBottom borderColor="border-charcoal-outline">
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
weight="medium"
|
||||
color="text-white"
|
||||
>
|
||||
{pts}
|
||||
</Text>
|
||||
</Box>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => updateRacePoints(idx, 1)}
|
||||
disabled={readOnly}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-5 w-4 p-0 rounded-l-none text-[10px]"
|
||||
>
|
||||
+
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
))}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
{/* Bonus points */}
|
||||
@@ -895,18 +1021,25 @@ export function ScoringPatternSection({
|
||||
{ key: 'leaderLapPoints' as const, label: 'Led lap', emoji: '🥇' },
|
||||
].map((bonus) => (
|
||||
<Stack key={bonus.key} align="center" gap={1}>
|
||||
<Text className="text-[10px] text-gray-500">{bonus.emoji} {bonus.label}</Text>
|
||||
<Stack direction="row" align="center" gap={0.5}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
>
|
||||
{bonus.emoji} {bonus.label}
|
||||
</Text>
|
||||
<Box display="flex" alignItems="center">
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => updateBonus(bonus.key, -1)}
|
||||
disabled={readOnly || customPoints[bonus.key] <= 0}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-6 w-5 p-0 rounded-r-none"
|
||||
>
|
||||
−
|
||||
</Button>
|
||||
<Box width={7} height={6} display="flex" center backgroundColor="deep-graphite" border borderTop borderBottom borderColor="charcoal-outline">
|
||||
<Box w="7" h="6" display="flex" alignItems="center" justifyContent="center" bg="bg-deep-graphite" border borderTop borderBottom borderColor="border-charcoal-outline">
|
||||
<Text size="xs" weight="medium" color="text-white">{customPoints[bonus.key]}</Text>
|
||||
</Box>
|
||||
<Button
|
||||
@@ -914,11 +1047,12 @@ export function ScoringPatternSection({
|
||||
size="sm"
|
||||
onClick={() => updateBonus(bonus.key, 1)}
|
||||
disabled={readOnly}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="h-6 w-5 p-0 rounded-l-none"
|
||||
>
|
||||
+
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
))}
|
||||
</Grid>
|
||||
@@ -1040,10 +1174,10 @@ export function ChampionshipsSection({
|
||||
<Stack gap={4}>
|
||||
{/* Section header */}
|
||||
<Stack direction="row" align="center" gap={3}>
|
||||
<Box width={10} height={10} display="flex" center rounded="xl" backgroundColor="primary-blue" opacity={0.1}>
|
||||
<Box w="10" h="10" display="flex" alignItems="center" justifyContent="center" rounded="xl" bg="bg-primary-blue" opacity={0.1}>
|
||||
<Icon icon={Award} size={5} color="text-primary-blue" />
|
||||
</Box>
|
||||
<Box flex={1}>
|
||||
<Box flexGrow={1}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Heading level={3}>Championships</Heading>
|
||||
<InfoButton buttonRef={champInfoRef} onClick={() => setShowChampFlyout(true)} />
|
||||
@@ -1066,15 +1200,33 @@ export function ChampionshipsSection({
|
||||
</Text>
|
||||
|
||||
<Box>
|
||||
<Box mb={2} className="text-[10px] text-gray-500 uppercase tracking-wide">
|
||||
<Text>Live Standings Example</Text>
|
||||
<Box mb={2}>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Live Standings Example
|
||||
</Text>
|
||||
</Box>
|
||||
<ChampionshipMockup />
|
||||
</Box>
|
||||
|
||||
<Stack gap={2}>
|
||||
<Box className="text-[10px] text-gray-500 uppercase tracking-wide">
|
||||
<Text>Championship Types</Text>
|
||||
<Box>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
Championship Types
|
||||
</Text>
|
||||
</Box>
|
||||
<Grid cols={2} gap={2}>
|
||||
{[
|
||||
@@ -1083,12 +1235,27 @@ export function ChampionshipsSection({
|
||||
{ icon: Globe, label: 'Nations', desc: 'By country' },
|
||||
{ icon: Medal, label: 'Trophy', desc: 'Special class' },
|
||||
].map((t, i) => (
|
||||
<Surface key={i} variant="dark" border rounded="lg" padding={2}>
|
||||
<Surface key={i} variant="dark" border rounded="lg" p={2}>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Icon icon={t.icon} size={3.5} color="text-primary-blue" />
|
||||
<Box>
|
||||
<Text className="text-[10px]" weight="medium" color="text-white" block>{t.label}</Text>
|
||||
<Text className="text-[9px] text-gray-500" block>{t.desc}</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
weight="medium"
|
||||
color="text-white"
|
||||
block
|
||||
>
|
||||
{t.label}
|
||||
</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '9px' }}
|
||||
color="text-gray-500"
|
||||
block
|
||||
>
|
||||
{t.desc}
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Surface>
|
||||
@@ -1110,6 +1277,7 @@ export function ChampionshipsSection({
|
||||
variant="ghost"
|
||||
disabled={disabled || !champ.available}
|
||||
onClick={() => champ.available && updateChampionship(champ.key, !champ.enabled)}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className={`
|
||||
w-full flex items-center gap-3 p-3 rounded-xl border-2 text-left transition-all duration-200 h-auto
|
||||
${isEnabled
|
||||
@@ -1122,34 +1290,54 @@ export function ChampionshipsSection({
|
||||
>
|
||||
{/* Toggle indicator */}
|
||||
<Box
|
||||
width={5}
|
||||
height={5}
|
||||
w="5"
|
||||
h="5"
|
||||
display="flex"
|
||||
center
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
rounded="md"
|
||||
backgroundColor={isEnabled ? 'primary-blue' : 'charcoal-outline'}
|
||||
bg={isEnabled ? 'bg-primary-blue' : 'bg-charcoal-outline'}
|
||||
opacity={isEnabled ? 1 : 0.5}
|
||||
className="shrink-0 transition-colors"
|
||||
transition
|
||||
flexShrink={0}
|
||||
>
|
||||
{isEnabled && <Icon icon={Check} size={3} color="text-white" />}
|
||||
</Box>
|
||||
|
||||
{/* Icon */}
|
||||
<Icon icon={champ.icon} size={4} color={isEnabled ? 'text-primary-blue' : 'text-gray-500'} className="shrink-0" />
|
||||
<Icon icon={champ.icon} size={4} color={isEnabled ? 'text-primary-blue' : 'text-gray-500'}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="shrink-0"
|
||||
/>
|
||||
|
||||
{/* Text */}
|
||||
<Box flex={1} className="min-w-0">
|
||||
<Text className={`text-xs font-medium truncate ${isEnabled ? 'text-white' : 'text-gray-400'}`} block>
|
||||
<Box flexGrow={1}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="min-w-0"
|
||||
>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className={`text-xs font-medium truncate ${isEnabled ? 'text-white' : 'text-gray-400'}`}
|
||||
block
|
||||
>
|
||||
{champ.label}
|
||||
</Text>
|
||||
{!champ.available && champ.unavailableHint && (
|
||||
<Text className="text-[10px] text-warning-amber/70" block>{champ.unavailableHint}</Text>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-warning-amber"
|
||||
opacity={0.7}
|
||||
block
|
||||
>
|
||||
{champ.unavailableHint}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* Info button */}
|
||||
<Box
|
||||
ref={(el: any) => { champItemRefs.current[champ.key] = el; }}
|
||||
ref={(el: HTMLElement | null) => { champItemRefs.current[champ.key] = el; }}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={(e: React.MouseEvent) => {
|
||||
@@ -1163,7 +1351,17 @@ export function ChampionshipsSection({
|
||||
setActiveChampFlyout(activeChampFlyout === champ.key ? null : champ.key);
|
||||
}
|
||||
}}
|
||||
className="flex h-5 w-5 items-center justify-center rounded-full text-gray-500 hover:text-primary-blue hover:bg-primary-blue/10 transition-colors shrink-0"
|
||||
display="flex"
|
||||
h="5"
|
||||
w="5"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
rounded="full"
|
||||
color="text-gray-500"
|
||||
hoverTextColor="text-primary-blue"
|
||||
hoverBg="bg-primary-blue/10"
|
||||
transition
|
||||
flexShrink={0}
|
||||
>
|
||||
<Icon icon={HelpCircle} size={3} />
|
||||
</Box>
|
||||
@@ -1175,19 +1373,34 @@ export function ChampionshipsSection({
|
||||
isOpen={activeChampFlyout === champ.key}
|
||||
onClose={() => setActiveChampFlyout(null)}
|
||||
title={champInfo.title}
|
||||
anchorRef={{ current: champItemRefs.current[champ.key] ?? champInfoRef.current }}
|
||||
anchorRef={{ current: (champItemRefs.current[champ.key] as HTMLElement | null) ?? champInfoRef.current }}
|
||||
>
|
||||
<Stack gap={4}>
|
||||
<Text size="xs" color="text-gray-400">{champInfo.description}</Text>
|
||||
|
||||
<Stack gap={2}>
|
||||
<Box className="text-[10px] text-gray-500 uppercase tracking-wide">
|
||||
<Text>How It Works</Text>
|
||||
<Box>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '10px' }}
|
||||
color="text-gray-500"
|
||||
transform="uppercase"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="tracking-wide"
|
||||
>
|
||||
How It Works
|
||||
</Text>
|
||||
</Box>
|
||||
<Box as="ul" className="space-y-1.5">
|
||||
<Box as="ul"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="space-y-1.5"
|
||||
>
|
||||
{champInfo.details.map((detail, idx) => (
|
||||
<Box as="li" key={idx} display="flex" align="start" gap={2}>
|
||||
<Icon icon={Check} size={3} color="text-performance-green" className="mt-0.5" />
|
||||
<Box as="li" key={idx} display="flex" alignItems="start" gap={2}>
|
||||
<Icon icon={Check} size={3} color="text-performance-green"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<Text size="xs" color="text-gray-400">{detail}</Text>
|
||||
</Box>
|
||||
))}
|
||||
@@ -1195,10 +1408,20 @@ export function ChampionshipsSection({
|
||||
</Stack>
|
||||
|
||||
{!champ.available && (
|
||||
<Surface variant="muted" border rounded="lg" padding={3} className="bg-warning-amber/5 border-warning-amber/20">
|
||||
<Surface variant="muted" border rounded="lg" p={3}
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="bg-warning-amber/5 border-warning-amber/20"
|
||||
>
|
||||
<Stack direction="row" align="start" gap={2}>
|
||||
<Icon icon={Zap} size={3.5} color="text-warning-amber" className="mt-0.5" />
|
||||
<Text className="text-[11px] text-gray-400">
|
||||
<Icon icon={Zap} size={3.5} color="text-warning-amber"
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<Text
|
||||
// eslint-disable-next-line gridpilot-rules/component-classification
|
||||
style={{ fontSize: '11px' }}
|
||||
color="text-gray-400"
|
||||
>
|
||||
<Text weight="medium" color="text-warning-amber">Note:</Text> {champ.unavailableHint}. Switch to Teams mode to enable this championship.
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user