website refactor
This commit is contained in:
@@ -8,8 +8,9 @@ import { Text } from '@/ui/Text';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Group } from '@/ui/Group';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { LeagueCard as UILeagueCard, LeagueCardStats, LeagueCardFooter } from '@/ui/LeagueCard';
|
||||
import { Calendar as LucideCalendar } from 'lucide-react';
|
||||
import { Calendar, Users, Activity } from 'lucide-react';
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
interface LeagueCardProps {
|
||||
@@ -54,80 +55,81 @@ export function LeagueCard({
|
||||
coverUrl={coverUrl}
|
||||
logo={
|
||||
<Surface
|
||||
width="3rem"
|
||||
height="3rem"
|
||||
rounded="md"
|
||||
width="3.5rem"
|
||||
height="3.5rem"
|
||||
rounded="lg"
|
||||
overflow="hidden"
|
||||
border
|
||||
variant="dark"
|
||||
variant="precision"
|
||||
>
|
||||
{logoUrl ? (
|
||||
<Image
|
||||
src={logoUrl}
|
||||
alt={`${name} logo`}
|
||||
width={48}
|
||||
height={48}
|
||||
width={56}
|
||||
height={56}
|
||||
objectFit="cover"
|
||||
/>
|
||||
) : (
|
||||
<PlaceholderImage size={48} />
|
||||
<PlaceholderImage size={56} />
|
||||
)}
|
||||
</Surface>
|
||||
}
|
||||
badges={
|
||||
<React.Fragment>
|
||||
<Group gap={2}>
|
||||
{badges}
|
||||
{championshipBadge}
|
||||
</React.Fragment>
|
||||
</Group>
|
||||
}
|
||||
>
|
||||
<Box marginBottom={1}>
|
||||
<Group gap={2}>
|
||||
<Box width="0.25rem" height="1rem" bg="var(--ui-color-intent-primary)" />
|
||||
<Heading level={3} weight="bold" truncate>{name}</Heading>
|
||||
</Group>
|
||||
</Box>
|
||||
|
||||
<Text size="xs" variant="low" lineClamp={2} style={{ height: '2.5rem' }} block leading="relaxed" marginBottom={4}>
|
||||
{description || 'No description available'}
|
||||
</Text>
|
||||
|
||||
<LeagueCardStats
|
||||
label={slotLabel}
|
||||
value={`${usedSlots}/${maxSlots || '∞'}`}
|
||||
percentage={fillPercentage}
|
||||
intent={fillPercentage >= 90 ? 'warning' : fillPercentage >= 70 ? 'primary' : 'success'}
|
||||
/>
|
||||
|
||||
{hasOpenSlots && (
|
||||
<Box marginBottom={4}>
|
||||
<Surface
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
gap={1.5}
|
||||
paddingX={2}
|
||||
paddingY={1}
|
||||
bg="rgba(25, 140, 255, 0.05)"
|
||||
border="1px solid rgba(25, 140, 255, 0.2)"
|
||||
rounded="sm"
|
||||
width="fit-content"
|
||||
>
|
||||
<Box width="0.375rem" height="0.375rem" rounded="full" bg="var(--ui-color-intent-primary)" />
|
||||
<Text size="xs" variant="primary" weight="bold" uppercase>{openSlotsCount} OPEN</Text>
|
||||
</Surface>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<LeagueCardFooter>
|
||||
{timingSummary && (
|
||||
<Group gap={2}>
|
||||
<Icon icon={LucideCalendar} size={3} intent="low" />
|
||||
<Text size="xs" variant="low" font="mono">
|
||||
{timingSummary.split('•')[1]?.trim() || timingSummary}
|
||||
</Text>
|
||||
<Stack gap={4} fullHeight>
|
||||
<Stack gap={1}>
|
||||
<Group gap={2} align="center">
|
||||
<Box width="2px" height="1rem" bg="var(--ui-color-intent-telemetry)" />
|
||||
<Heading level={3} weight="bold" truncate>{name}</Heading>
|
||||
</Group>
|
||||
)}
|
||||
</LeagueCardFooter>
|
||||
<Text size="xs" variant="low" lineClamp={2} block leading="relaxed">
|
||||
{description || 'No infrastructure description provided.'}
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
<Box>
|
||||
<LeagueCardStats
|
||||
label={slotLabel}
|
||||
value={`${usedSlots} / ${maxSlots || '∞'}`}
|
||||
percentage={fillPercentage}
|
||||
intent={fillPercentage >= 90 ? 'warning' : fillPercentage >= 70 ? 'primary' : 'success'}
|
||||
/>
|
||||
|
||||
{hasOpenSlots && (
|
||||
<Group gap={2} align="center">
|
||||
<Icon icon={Activity} size={3} intent="success" />
|
||||
<Text size="xs" variant="success" weight="bold" uppercase font="mono">
|
||||
{openSlotsCount} slots available
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<LeagueCardFooter>
|
||||
<Stack gap={2}>
|
||||
{timingSummary && (
|
||||
<Group gap={2}>
|
||||
<Icon icon={Calendar} size={3} intent="low" />
|
||||
<Text size="xs" variant="low" font="mono">
|
||||
{timingSummary.split('•')[1]?.trim() || timingSummary}
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
<Group gap={2}>
|
||||
<Icon icon={Users} size={3} intent="low" />
|
||||
<Text size="xs" variant="low" font="mono">
|
||||
{usedSlots} active participants
|
||||
</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
</LeagueCardFooter>
|
||||
</Stack>
|
||||
</UILeagueCard>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
Flag,
|
||||
Award,
|
||||
Sparkles,
|
||||
Gamepad2,
|
||||
Layers,
|
||||
} from 'lucide-react';
|
||||
import type { LeagueSummaryViewModel } from '@/lib/view-models/LeagueSummaryViewModel';
|
||||
import { getMediaUrl } from '@/lib/utilities/media';
|
||||
@@ -152,24 +154,24 @@ export function LeagueCard({ league, onClick }: LeagueCardProps) {
|
||||
badges={
|
||||
<>
|
||||
{isNew && (
|
||||
<Badge variant="success" icon={Sparkles}>
|
||||
<Badge variant="success" icon={Sparkles} size="sm">
|
||||
NEW
|
||||
</Badge>
|
||||
)}
|
||||
{league.scoring?.gameName && (
|
||||
<Badge variant={gameVariant}>
|
||||
<Badge variant={gameVariant} icon={Gamepad2} size="sm">
|
||||
{league.scoring.gameName}
|
||||
</Badge>
|
||||
)}
|
||||
{league.category && (
|
||||
<Badge variant={categoryVariant}>
|
||||
<Badge variant={categoryVariant} icon={Layers} size="sm">
|
||||
{categoryLabel}
|
||||
</Badge>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
championshipBadge={
|
||||
<Badge variant="default" icon={ChampionshipIcon}>
|
||||
<Badge variant="outline" icon={ChampionshipIcon} size="sm">
|
||||
{championshipLabel}
|
||||
</Badge>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user