website refactor
This commit is contained in:
118
apps/website/templates/RacesIndexTemplate.tsx
Normal file
118
apps/website/templates/RacesIndexTemplate.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Container } from '@/ui/Container';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { RacesLiveRail } from '@/components/races/RacesLiveRail';
|
||||
import { RacesCommandBar } from '@/components/races/RacesCommandBar';
|
||||
import { NextUpRacePanel } from '@/components/races/NextUpRacePanel';
|
||||
import { RacesDayGroup } from '@/components/races/RacesDayGroup';
|
||||
import { RacesEmptyState } from '@/components/races/RacesEmptyState';
|
||||
import { RaceFilterModal } from '@/components/races/RaceFilterModal';
|
||||
import { PageHeader } from '@/components/shared/PageHeader';
|
||||
import type { RacesViewData } from '@/lib/view-data/RacesViewData';
|
||||
|
||||
export interface RacesIndexTemplateProps {
|
||||
viewData: RacesViewData & {
|
||||
racesByDate: Array<{
|
||||
dateKey: string;
|
||||
dateLabel: string;
|
||||
races: any[];
|
||||
}>;
|
||||
nextUpRace?: any;
|
||||
};
|
||||
// Filters
|
||||
statusFilter: string;
|
||||
setStatusFilter: (filter: any) => void;
|
||||
leagueFilter: string;
|
||||
setLeagueFilter: (filter: string) => void;
|
||||
timeFilter: string;
|
||||
setTimeFilter: (filter: any) => void;
|
||||
// Actions
|
||||
onRaceClick: (raceId: string) => void;
|
||||
// UI State
|
||||
showFilterModal: boolean;
|
||||
setShowFilterModal: (show: boolean) => void;
|
||||
}
|
||||
|
||||
export function RacesIndexTemplate({
|
||||
viewData,
|
||||
statusFilter,
|
||||
setStatusFilter,
|
||||
leagueFilter,
|
||||
setLeagueFilter,
|
||||
timeFilter,
|
||||
setTimeFilter,
|
||||
onRaceClick,
|
||||
showFilterModal,
|
||||
setShowFilterModal,
|
||||
}: RacesIndexTemplateProps) {
|
||||
const hasRaces = viewData.racesByDate.length > 0;
|
||||
|
||||
return (
|
||||
<Container size="lg">
|
||||
<Stack gap={8} paddingY={12}>
|
||||
<PageHeader
|
||||
title="Races"
|
||||
subtitle="Live Sessions & Upcoming Events"
|
||||
/>
|
||||
|
||||
{/* 1. Status Rail: Live sessions first */}
|
||||
<RacesLiveRail
|
||||
liveRaces={viewData.liveRaces}
|
||||
onRaceClick={onRaceClick}
|
||||
/>
|
||||
|
||||
{/* 2. Command Bar: Fast filters */}
|
||||
<RacesCommandBar
|
||||
timeFilter={timeFilter}
|
||||
setTimeFilter={setTimeFilter}
|
||||
leagueFilter={leagueFilter}
|
||||
setLeagueFilter={setLeagueFilter}
|
||||
leagues={viewData.leagues}
|
||||
onShowMoreFilters={() => setShowFilterModal(true)}
|
||||
/>
|
||||
|
||||
{/* 3. Next Up: High signal panel */}
|
||||
{timeFilter === 'upcoming' && viewData.nextUpRace && (
|
||||
<NextUpRacePanel
|
||||
race={viewData.nextUpRace}
|
||||
onRaceClick={onRaceClick}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 4. Browse by Day: Grouped schedule */}
|
||||
{hasRaces ? (
|
||||
<Stack gap={8}>
|
||||
{viewData.racesByDate.map((group) => (
|
||||
<RacesDayGroup
|
||||
key={group.dateKey}
|
||||
dateLabel={group.dateLabel}
|
||||
races={group.races}
|
||||
onRaceClick={onRaceClick}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
) : (
|
||||
<RacesEmptyState />
|
||||
)}
|
||||
|
||||
<RaceFilterModal
|
||||
isOpen={showFilterModal}
|
||||
onClose={() => setShowFilterModal(false)}
|
||||
statusFilter={statusFilter as any}
|
||||
setStatusFilter={setStatusFilter}
|
||||
leagueFilter={leagueFilter}
|
||||
setLeagueFilter={setLeagueFilter}
|
||||
timeFilter={timeFilter as any}
|
||||
setTimeFilter={setTimeFilter}
|
||||
searchQuery=""
|
||||
setSearchQuery={() => {}}
|
||||
leagues={viewData.leagues}
|
||||
showSearch={true}
|
||||
showTimeFilter={false}
|
||||
/>
|
||||
</Stack>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -11,9 +11,7 @@ import type { RacesViewData } from '@/lib/view-data/RacesViewData';
|
||||
import { Container } from '@/ui/Container';
|
||||
import { Grid } from '@/ui/Grid';
|
||||
import { GridItem } from '@/ui/GridItem';
|
||||
import { Group } from '@/ui/Group';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Panel } from '@/ui/Panel';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import React from 'react';
|
||||
|
||||
export type TimeFilter = 'all' | 'upcoming' | 'live' | 'past';
|
||||
@@ -51,8 +49,8 @@ export function RacesTemplate({
|
||||
setShowFilterModal,
|
||||
}: RacesTemplateProps) {
|
||||
return (
|
||||
<Container size="lg" py={8}>
|
||||
<Group direction="column" gap={8} fullWidth>
|
||||
<Container size="lg">
|
||||
<Stack gap={8}>
|
||||
<RacePageHeader
|
||||
totalCount={viewData.totalCount}
|
||||
scheduledCount={viewData.scheduledCount}
|
||||
@@ -67,7 +65,7 @@ export function RacesTemplate({
|
||||
|
||||
<Grid cols={12} gap={6}>
|
||||
<GridItem colSpan={12} lgSpan={8}>
|
||||
<Group direction="column" gap={6} fullWidth>
|
||||
<Stack gap={6}>
|
||||
<RaceFilterBar
|
||||
timeFilter={timeFilter}
|
||||
setTimeFilter={setTimeFilter}
|
||||
@@ -77,24 +75,18 @@ export function RacesTemplate({
|
||||
onShowMoreFilters={() => setShowFilterModal(true)}
|
||||
/>
|
||||
|
||||
<Panel
|
||||
title="Race Schedule"
|
||||
variant="dark"
|
||||
padding={0}
|
||||
>
|
||||
<RaceScheduleTable
|
||||
races={viewData.races.map(race => ({
|
||||
id: race.id,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
leagueName: race.leagueName,
|
||||
time: race.timeLabel,
|
||||
status: race.status as SessionStatus
|
||||
}))}
|
||||
onRaceClick={onRaceClick}
|
||||
/>
|
||||
</Panel>
|
||||
</Group>
|
||||
<RaceScheduleTable
|
||||
races={viewData.races.map(race => ({
|
||||
id: race.id,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
leagueName: race.leagueName,
|
||||
time: race.timeLabel,
|
||||
status: race.status as SessionStatus
|
||||
}))}
|
||||
onRaceClick={onRaceClick}
|
||||
/>
|
||||
</Stack>
|
||||
</GridItem>
|
||||
|
||||
<GridItem colSpan={12} lgSpan={4}>
|
||||
@@ -121,7 +113,7 @@ export function RacesTemplate({
|
||||
showSearch={false}
|
||||
showTimeFilter={false}
|
||||
/>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user