123 lines
5.2 KiB
TypeScript
123 lines
5.2 KiB
TypeScript
'use client';
|
|
|
|
import { routes } from '@/lib/routing/RouteConfig';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Button } from '@/ui/Button';
|
|
import { Container } from '@/ui/Container';
|
|
import { Grid } from '@/ui/Grid';
|
|
import { Heading } from '@/ui/Heading';
|
|
import { Link } from '@/ui/Link';
|
|
import { Text } from '@/ui/Text';
|
|
import { LeagueCard } from '@/components/leagues/LeagueCard';
|
|
import { TeamCard } from '@/components/teams/TeamCard';
|
|
import { UpcomingRaceItem } from '@/components/races/UpcomingRaceItem';
|
|
import { HomeViewData } from '@/templates/HomeTemplate';
|
|
|
|
interface DiscoverySectionProps {
|
|
viewData: HomeViewData;
|
|
}
|
|
|
|
export function DiscoverySection({ viewData }: DiscoverySectionProps) {
|
|
return (
|
|
<Stack py={{ base: 20, md: 32 }} bg="graphite-black" borderBottom borderColor="border-gray/50">
|
|
<Container size="lg">
|
|
<Stack gap={16}>
|
|
<Stack maxWidth="2xl">
|
|
<Stack borderLeft borderStyle="solid" borderColor="primary-accent" pl={4} mb={4}>
|
|
<Text size="xs" weight="bold" variant="primary" uppercase letterSpacing="0.2em">
|
|
Live Ecosystem
|
|
</Text>
|
|
</Stack>
|
|
<Heading level={2} weight="bold" fontSize={{ base: '3xl', md: '4xl' }} letterSpacing="-0.025em">
|
|
Discover the Grid
|
|
</Heading>
|
|
<Text size="lg" color="text-gray-400" block mt={6} leading="relaxed">
|
|
Explore leagues, teams, and races that make up the GridPilot ecosystem.
|
|
</Text>
|
|
</Stack>
|
|
|
|
<Grid cols={1} lgCols={3} gap={12}>
|
|
{/* Top leagues */}
|
|
<Stack gap={8}>
|
|
<Stack direction="row" align="center" justify="between" borderBottom borderColor="var(--ui-color-border-low)" pb={4}>
|
|
<Heading level={5} color="var(--ui-color-text-low)" weight="bold" letterSpacing="widest" uppercase>FEATURED LEAGUES</Heading>
|
|
<Link href={routes.public.leagues}>
|
|
<Text size="xs" weight="bold" variant="primary" uppercase letterSpacing="widest" hoverVariant="high">View all</Text>
|
|
</Link>
|
|
</Stack>
|
|
<Stack gap={4}>
|
|
{viewData.topLeagues.slice(0, 2).map((league) => (
|
|
<LeagueCard
|
|
key={league.id}
|
|
name={league.name}
|
|
description={league.description}
|
|
coverUrl="/images/ff1600.jpeg"
|
|
slotLabel="Drivers"
|
|
usedSlots={18}
|
|
maxSlots={24}
|
|
fillPercentage={75}
|
|
hasOpenSlots={true}
|
|
openSlotsCount={6}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
</Stack>
|
|
|
|
{/* Teams */}
|
|
<Stack gap={8}>
|
|
<Stack direction="row" align="center" justify="between" borderBottom borderColor="var(--ui-color-border-low)" pb={4}>
|
|
<Heading level={5} color="var(--ui-color-text-low)" weight="bold" letterSpacing="widest" uppercase>TEAMS ON THE GRID</Heading>
|
|
<Link href={routes.public.teams}>
|
|
<Text size="xs" weight="bold" variant="primary" uppercase letterSpacing="widest" hoverVariant="high">Browse</Text>
|
|
</Link>
|
|
</Stack>
|
|
<Stack gap={4}>
|
|
{viewData.teams.slice(0, 2).map(team => (
|
|
<TeamCard
|
|
key={team.id}
|
|
name={team.name}
|
|
description={team.description}
|
|
logo={team.logoUrl}
|
|
memberCount={12}
|
|
isRecruiting={true}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
</Stack>
|
|
|
|
{/* Upcoming races */}
|
|
<Stack gap={8}>
|
|
<Stack direction="row" align="center" justify="between" borderBottom borderColor="var(--ui-color-border-low)" pb={4}>
|
|
<Heading level={5} color="var(--ui-color-text-low)" weight="bold" letterSpacing="widest" uppercase>UPCOMING RACES</Heading>
|
|
<Link href={routes.public.races}>
|
|
<Text size="xs" weight="bold" variant="primary" uppercase letterSpacing="widest" hoverVariant="high">Schedule</Text>
|
|
</Link>
|
|
</Stack>
|
|
{viewData.upcomingRaces.length === 0 ? (
|
|
<Stack p={12} border borderStyle="dashed" borderColor="border-gray/30" rounded="none" center bg="panel-gray/10">
|
|
<Text size="sm" color="text-gray-600" font="mono" uppercase letterSpacing="widest">
|
|
No races scheduled.
|
|
</Text>
|
|
</Stack>
|
|
) : (
|
|
<Stack gap={3}>
|
|
{viewData.upcomingRaces.map(race => (
|
|
<UpcomingRaceItem
|
|
key={race.id}
|
|
track={race.track}
|
|
car={race.car}
|
|
formattedDate={race.formattedDate}
|
|
formattedTime="20:00 GMT"
|
|
isMyLeague={false}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
)}
|
|
</Stack>
|
|
</Grid>
|
|
</Stack>
|
|
</Container>
|
|
</Stack>
|
|
);
|
|
}
|