website refactor

This commit is contained in:
2026-01-21 18:40:49 +01:00
parent 69319ce1d4
commit ea58909070
18 changed files with 1051 additions and 267 deletions

View File

@@ -11,24 +11,21 @@ import { Icon } from '@/ui/Icon';
import { Group } from '@/ui/Group';
import { Calendar, Plus } from 'lucide-react';
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
import {
registerForRaceAction,
withdrawFromRaceAction,
navigateToEditRaceAction,
navigateToRescheduleRaceAction,
navigateToRaceResultsAction
} from '@/app/actions/leagueScheduleActions';
interface LeagueScheduleTemplateProps {
viewData: LeagueScheduleViewData;
onRegister: (raceId: string) => Promise<void>;
onWithdraw: (raceId: string) => Promise<void>;
onEdit: (raceId: string) => void;
onReschedule: (raceId: string) => void;
onResultsClick: (raceId: string) => void;
onCreateRace?: () => void;
}
export function LeagueScheduleTemplate({
viewData,
onRegister,
onWithdraw,
onEdit,
onReschedule,
onResultsClick,
onCreateRace
}: LeagueScheduleTemplateProps) {
const [selectedRace, setSelectedRace] = useState<{
@@ -85,15 +82,27 @@ export function LeagueScheduleTemplate({
};
const handleRegister = async (raceId: string) => {
await onRegister(raceId);
await registerForRaceAction(raceId, viewData.leagueId, viewData.currentDriverId || '');
setModalOpen(false);
};
const handleWithdraw = async (raceId: string) => {
await onWithdraw(raceId);
await withdrawFromRaceAction(raceId, viewData.currentDriverId || '', viewData.leagueId);
setModalOpen(false);
};
const handleEdit = (raceId: string) => {
navigateToEditRaceAction(raceId, viewData.leagueId);
};
const handleReschedule = (raceId: string) => {
navigateToRescheduleRaceAction(raceId, viewData.leagueId);
};
const handleResultsClick = (raceId: string) => {
navigateToRaceResultsAction(raceId, viewData.leagueId);
};
return (
<Box display="flex" flexDirection="col" gap={8}>
<Box as="header" display="flex" flexDirection="col" gap={2}>
@@ -122,10 +131,10 @@ export function LeagueScheduleTemplate({
isAdmin={viewData.isAdmin}
onRegister={handleRegister}
onWithdraw={handleWithdraw}
onEdit={onEdit}
onReschedule={onReschedule}
onEdit={handleEdit}
onReschedule={handleReschedule}
onRaceDetail={handleRaceDetail}
onResultsClick={onResultsClick}
onResultsClick={handleResultsClick}
/>
{selectedRace && (
@@ -135,7 +144,7 @@ export function LeagueScheduleTemplate({
onClose={handleCloseModal}
onRegister={() => handleRegister(selectedRace.id)}
onWithdraw={() => handleWithdraw(selectedRace.id)}
onResultsClick={() => onResultsClick(selectedRace.id)}
onResultsClick={() => handleResultsClick(selectedRace.id)}
/>
)}
</Box>

View File

@@ -3,7 +3,9 @@
import { LeagueCard } from '@/components/leagues/LeagueCardWrapper';
import type { LeaguesViewData } from '@/lib/view-data/LeaguesViewData';
import { LeagueSummaryViewModel } from '@/lib/view-models/LeagueSummaryViewModel';
import { LEAGUE_CATEGORIES, CategoryId, LeagueCategory } from '@/lib/config/leagueCategories';
import { PageHeader } from '@/ui/PageHeader';
import { Heading } from '@/ui/Heading';
import { Input } from '@/ui/Input';
import { Button } from '@/ui/Button';
import { Group } from '@/ui/Group';
@@ -22,39 +24,19 @@ import {
Search,
Trophy,
Filter,
Sparkles,
type LucideIcon,
} from 'lucide-react';
import React from 'react';
import { TemplateProps } from '@/lib/contracts/components/ComponentContracts';
export type CategoryId =
| 'all'
| 'driver'
| 'team'
| 'nations'
| 'trophy'
| 'new'
| 'popular'
| 'openSlots'
| 'endurance'
| 'sprint';
export interface Category {
id: CategoryId;
label: string;
icon: LucideIcon;
description: string;
filter: (league: LeaguesViewData['leagues'][number]) => boolean;
color?: string;
}
interface LeaguesTemplateProps extends TemplateProps<LeaguesViewData> {
searchQuery: string;
onSearchChange: (query: string) => void;
activeCategory: CategoryId;
onCategoryChange: (id: CategoryId) => void;
filteredLeagues: LeaguesViewData['leagues'];
categories: Category[];
categories: LeagueCategory[];
onCreateLeague: () => void;
onLeagueClick: (id: string) => void;
onClearFilters: () => void;
@@ -114,6 +96,30 @@ export function LeaguesTemplate({
/>
</FeatureGrid>
{/* Featured Leagues Section */}
{viewData.leagues.filter(l => (l.usedDriverSlots ?? 0) > 20).length > 0 && (
<Stack gap={4}>
<Group align="center" gap={2}>
<Icon icon={Sparkles} size={5} intent="warning" />
<Heading level={3} weight="bold" uppercase letterSpacing="wider">Featured Leagues</Heading>
</Group>
<Surface variant="dark" padding={6} rounded="2xl" border borderColor="var(--ui-color-intent-warning-muted)">
<FeatureGrid columns={{ base: 1, md: 2 }} gap={6}>
{viewData.leagues
.filter(l => (l.usedDriverSlots ?? 0) > 20)
.slice(0, 2)
.map((league) => (
<LeagueCard
key={`featured-${league.id}`}
league={league as unknown as LeagueSummaryViewModel}
onClick={() => onLeagueClick(league.id)}
/>
))}
</FeatureGrid>
</Surface>
</Stack>
)}
{/* Control Bar */}
<ControlBar
leftContent={