website refactor
This commit is contained in:
@@ -3,19 +3,16 @@
|
||||
import { RaceFilterModal } from '@/components/races/RaceFilterModal';
|
||||
import { RacePageHeader } from '@/components/races/RacePageHeader';
|
||||
import { RaceScheduleTable } from '@/components/races/RaceScheduleTable';
|
||||
import { RacesAllLayout, RacesAllStats } from '@/components/races/RacesAllLayout';
|
||||
import { RaceScheduleSection } from '@/components/races/RacesLayout';
|
||||
import type { SessionStatus } from '@/components/races/SessionStatusBadge';
|
||||
import type { RacesViewData } from '@/lib/view-data/RacesViewData';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Container } from '@/ui/Container';
|
||||
import { Pagination } from '@/ui/Pagination';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Skeleton } from '@/ui/Skeleton';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { SharedPagination, SharedText, SharedBox } from '@/components/shared/UIComponents';
|
||||
import { TemplateProps } from '@/lib/contracts/components/ComponentContracts';
|
||||
|
||||
export type StatusFilter = 'scheduled' | 'running' | 'completed' | 'cancelled' | 'all';
|
||||
|
||||
interface RacesAllTemplateProps {
|
||||
viewData: RacesViewData;
|
||||
interface RacesAllTemplateProps extends TemplateProps<RacesViewData> {
|
||||
races: RacesViewData['races'];
|
||||
totalFilteredCount: number;
|
||||
isLoading: boolean;
|
||||
@@ -60,100 +57,67 @@ export function RacesAllTemplate({
|
||||
setShowFilterModal,
|
||||
onRaceClick,
|
||||
}: RacesAllTemplateProps) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Container size="lg" py={8}>
|
||||
<Stack gap={6}>
|
||||
<Skeleton width="100%" height="12rem" />
|
||||
<Stack gap={4}>
|
||||
{[1, 2, 3, 4, 5].map(i => (
|
||||
<Skeleton key={i} width="100%" height="4rem" />
|
||||
))}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
// Note: Loading state is handled by StatefulPageWrapper in the client wrapper
|
||||
|
||||
return (
|
||||
<Box as="main" minHeight="screen" bg="bg-base-black" py={8}>
|
||||
<Container size="lg">
|
||||
<Stack gap={8}>
|
||||
<RacePageHeader
|
||||
totalCount={viewData.totalCount}
|
||||
scheduledCount={viewData.scheduledCount}
|
||||
runningCount={viewData.runningCount}
|
||||
completedCount={viewData.completedCount}
|
||||
<RacesAllLayout
|
||||
header={
|
||||
<RacePageHeader
|
||||
totalCount={viewData.totalCount}
|
||||
scheduledCount={viewData.scheduledCount}
|
||||
runningCount={viewData.runningCount}
|
||||
completedCount={viewData.completedCount}
|
||||
/>
|
||||
}
|
||||
stats={
|
||||
<RacesAllStats
|
||||
count={totalFilteredCount}
|
||||
onFilterClick={() => setShowFilterModal(true)}
|
||||
/>
|
||||
}
|
||||
pagination={
|
||||
<SharedPagination
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<RaceScheduleSection title="Race Schedule">
|
||||
{races.length === 0 ? (
|
||||
<SharedBox p={12} textAlign="center">
|
||||
<SharedText color="text-gray-500">No races found matching your criteria.</SharedText>
|
||||
</SharedBox>
|
||||
) : (
|
||||
<RaceScheduleTable
|
||||
races={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}
|
||||
/>
|
||||
)}
|
||||
</RaceScheduleSection>
|
||||
|
||||
<Box display="flex" justifyContent="between" alignItems="center">
|
||||
<Text size="sm" color="text-gray-400">
|
||||
Showing <Text as="span" color="text-white" weight="bold">{totalFilteredCount}</Text> races
|
||||
</Text>
|
||||
<Box
|
||||
as="button"
|
||||
onClick={() => setShowFilterModal(true)}
|
||||
px={4}
|
||||
py={2}
|
||||
bg="bg-surface-charcoal"
|
||||
border
|
||||
borderColor="border-outline-steel"
|
||||
fontSize="10px"
|
||||
weight="bold"
|
||||
uppercase
|
||||
letterSpacing="wider"
|
||||
hoverBorderColor="border-primary-accent"
|
||||
transition
|
||||
>
|
||||
Filters
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box as="section" bg="bg-surface-charcoal" border borderColor="border-outline-steel" overflow="hidden">
|
||||
{races.length === 0 ? (
|
||||
<Box p={12} textAlign="center">
|
||||
<Text color="text-gray-500">No races found matching your criteria.</Text>
|
||||
</Box>
|
||||
) : (
|
||||
<RaceScheduleTable
|
||||
races={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}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
totalItems={totalFilteredCount}
|
||||
itemsPerPage={itemsPerPage}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
|
||||
<RaceFilterModal
|
||||
isOpen={showFilterModal}
|
||||
onClose={() => setShowFilterModal(false)}
|
||||
statusFilter={statusFilter}
|
||||
setStatusFilter={setStatusFilter}
|
||||
leagueFilter={leagueFilter}
|
||||
setLeagueFilter={setLeagueFilter}
|
||||
timeFilter="all"
|
||||
setTimeFilter={() => {}}
|
||||
searchQuery={searchQuery}
|
||||
setSearchQuery={setSearchQuery}
|
||||
leagues={viewData.leagues}
|
||||
showSearch={true}
|
||||
showTimeFilter={false}
|
||||
/>
|
||||
</Stack>
|
||||
</Container>
|
||||
</Box>
|
||||
<RaceFilterModal
|
||||
isOpen={showFilterModal}
|
||||
onClose={() => setShowFilterModal(false)}
|
||||
statusFilter={statusFilter}
|
||||
setStatusFilter={setStatusFilter}
|
||||
leagueFilter={leagueFilter}
|
||||
setLeagueFilter={setLeagueFilter}
|
||||
timeFilter="all"
|
||||
setTimeFilter={() => {}}
|
||||
searchQuery={searchQuery}
|
||||
setSearchQuery={setSearchQuery}
|
||||
leagues={viewData.leagues}
|
||||
showSearch={true}
|
||||
showTimeFilter={false}
|
||||
/>
|
||||
</RacesAllLayout>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user