code quality
Some checks failed
CI / lint-typecheck (pull_request) Failing after 12s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped

This commit is contained in:
2026-01-26 22:16:33 +01:00
parent f2bd80ccd3
commit 09632d004d
72 changed files with 1946 additions and 277 deletions

View File

@@ -15,6 +15,7 @@ import { Container } from '@/ui/Container';
import { ErrorBanner } from '@/ui/ErrorBanner';
import { Stack } from '@/ui/Stack';
import { RefreshCw, ShieldAlert, Users } from 'lucide-react';
import { Icon } from '@/ui/Icon';
// We need to add InlineNotice to UIComponents if it's used
// For now I'll assume it's a component or I'll add it to UIComponents

View File

@@ -60,12 +60,15 @@ export function LeagueAdminScheduleTemplate({
setCar,
setScheduledAtIso,
}: LeagueAdminScheduleTemplateProps) {
const { races, seasons, seasonId, published } = viewData;
const typedViewData = viewData as LeagueAdminScheduleViewData & {
seasons: Array<{ seasonId: string; name: string }>;
};
const { races, seasons, seasonId, published } = typedViewData;
const isEditing = editingRaceId !== null;
const publishedLabel = published ? 'Published' : 'Unpublished';
const selectedSeasonLabel = seasons.find((s) => s.seasonId === seasonId)?.name ?? seasonId;
const selectedSeasonLabel = seasons.find((s: {seasonId: string; name: string}) => s.seasonId === seasonId)?.name ?? seasonId;
return (
<Stack gap={6}>
@@ -88,7 +91,7 @@ export function LeagueAdminScheduleTemplate({
<Select
value={seasonId}
onChange={(e) => onSeasonChange(e.target.value)}
options={seasons.map(s => ({ value: s.seasonId, label: s.name }))}
options={seasons.map((s: {seasonId: string; name: string}) => ({ value: s.seasonId, label: s.name }))}
/>
<Text size="xs" color="text-gray-500" block mt={1}>Selected: {selectedSeasonLabel}</Text>
</Box>

View File

@@ -1,5 +1,6 @@
'use client';
import { TemplateProps } from '@/lib/contracts/components/ComponentContracts';
import type { LeagueDetailViewData } from '@/lib/view-data/LeagueDetailViewData';
import { Box } from '@/ui/Box';
@@ -20,7 +21,7 @@ export function LeagueDetailTemplate({ viewData, children, tabs }: TemplateProps
<Stack gap={8}>
<Box>
<Stack direction="row" align="center" gap={2}>
<Link href={routes.public.leagues}>
<Link href="/leagues">
<Text size="sm" color="text-gray-400">Leagues</Text>
</Link>
<Icon icon={ChevronRight} size={3} color="text-gray-500" />

View File

@@ -1,3 +1,4 @@
'use client';
import {
navigateToEditRaceAction,
navigateToRaceResultsAction,

View File

@@ -1,5 +1,6 @@
'use client';
import { LeagueStandingsTable } from '@/components/leagues/LeagueStandingsTable';
import type { LeagueStandingsViewData } from '@/lib/view-data/LeagueStandingsViewData';
import { Box } from '@/ui/Box';

View File

@@ -40,7 +40,11 @@ export function LeagueWalletTemplate({ viewData, onExport }: LeagueWalletTemplat
<WalletSummaryPanel
formattedBalance={viewData.formattedBalance}
currency="USD"
transactions={viewData.transactions}
transactions={viewData.transactions.map((t: any) => ({
...t,
formattedAmount: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(t.amount),
formattedDate: new Date(t.createdAt).toLocaleDateString('en-US'),
}))}
onDeposit={() => {}} // Not implemented for leagues yet
onWithdraw={() => {}} // Not implemented for leagues yet
/>

View File

@@ -11,6 +11,7 @@ import { Heading } from '@/ui/Heading';
import { MediaMetaPanel, mapMediaMetadata } from '@/ui/MediaMetaPanel';
import { MediaPreviewCard } from '@/ui/MediaPreviewCard';
import { Text } from '@/ui/Text';
import { Box } from '@/ui/Box';
import Link from 'next/link';
interface ProfileLiveryUploadTemplateProps extends TemplateProps<ViewData> {

View File

@@ -1,5 +1,6 @@
'use client';
import { routes } from '@/lib/routing/RouteConfig';
import { Box } from '@/ui/Box';
import { Icon } from '@/ui/Icon';

View File

@@ -24,6 +24,7 @@ import {
Flag,
Gavel,
MapPin,
Calendar,
MessageCircle,
Send,
User,

View File

@@ -119,9 +119,9 @@ export function RaceStewardingTemplate({
</Box>
) : (
viewData.pendingProtests.map((protest) => (
<ProtestCard
key={protest.id}
protest={protest}
<ProtestCard
key={protest.id}
protest={{ ...protest, proofVideoUrl: protest.proofVideoUrl ?? undefined, decisionNotes: protest.decisionNotes ?? undefined }}
protester={viewData.driverMap[protest.protestingDriverId]}
accused={viewData.driverMap[protest.accusedDriverId]}
isAdmin={isAdmin}
@@ -147,9 +147,9 @@ export function RaceStewardingTemplate({
</Box>
) : (
viewData.resolvedProtests.map((protest) => (
<ProtestCard
key={protest.id}
protest={protest}
<ProtestCard
key={protest.id}
protest={{ ...protest, proofVideoUrl: protest.proofVideoUrl ?? undefined, decisionNotes: protest.decisionNotes ?? undefined }}
protester={viewData.driverMap[protest.protestingDriverId]}
accused={viewData.driverMap[protest.accusedDriverId]}
isAdmin={isAdmin}
@@ -180,6 +180,7 @@ export function RaceStewardingTemplate({
penalty={{
...penalty,
driverName: viewData.driverMap[penalty.driverId]?.name || 'Unknown',
notes: penalty.notes ?? undefined,
type: penalty.type as 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points'
}}
/>

View File

@@ -5,6 +5,7 @@ import { RacesCommandBar } from '@/components/races/RacesCommandBar';
import { RacesDayGroup } from '@/components/races/RacesDayGroup';
import { RacesEmptyState } from '@/components/races/RacesEmptyState';
import { RacesLiveRail } from '@/components/races/RacesLiveRail';
import { RaceFilterModal } from '@/components/races/RaceFilterModal';
import type { RacesViewData, RaceViewData } from '@/lib/view-data/RacesViewData';
import { PageHeader } from '@/ui/PageHeader';
import { Section } from '@/ui/Section';

View File

@@ -1,5 +1,6 @@
'use client';
import { RulebookTabs, type RulebookSection } from '@/components/leagues/RulebookTabs';
import { PointsTable } from '@/components/races/PointsTable';
import type { RulebookViewData } from '@/lib/view-data/RulebookViewData';

View File

@@ -74,7 +74,7 @@ export function SponsorDashboardTemplate({ viewData }: SponsorDashboardTemplateP
},
];
const activities: Activity[] = viewData.recentActivity.map(a => ({
const activities: Activity[] = viewData.recentActivity.map((a: any) => ({
id: a.id,
type: 'sponsorship_approved', // Mapping logic would go here
title: a.message,
@@ -108,14 +108,14 @@ export function SponsorDashboardTemplate({ viewData }: SponsorDashboardTemplateP
<MetricCard
title="Unique Viewers"
value="12.5k"
change={viewData.metrics.viewersChange}
change={viewData.metrics.impressionsChange}
icon={Users}
delay={0.1}
/>
<MetricCard
title="Engagement Rate"
value="4.2%"
change={viewData.metrics.exposureChange}
change={viewData.metrics.impressionsChange}
icon={TrendingUp}
suffix="%"
delay={0.2}
@@ -291,7 +291,7 @@ export function SponsorDashboardTemplate({ viewData }: SponsorDashboardTemplateP
</Stack>
</Heading>
<Stack gap={3}>
{viewData.upcomingRenewals.map((renewal) => (
{viewData.upcomingRenewals.map((renewal: any) => (
<RenewalAlert key={renewal.id} renewal={renewal} />
))}
</Stack>

View File

@@ -1,6 +1,7 @@
import { TeamAdmin } from '@/components/teams/TeamAdmin';
import { TeamDetailsHeader } from '@/components/teams/TeamDetailsHeader';
import { TeamMembersTable } from '@/components/teams/TeamMembersTable';
import { TeamStandingsPanel } from '@/components/teams/TeamStandingsPanel';
import type { TeamDetailViewData } from '@/lib/view-data/TeamDetailViewData';

View File

@@ -10,6 +10,7 @@ import { Panel } from '@/ui/Panel';
import { Section } from '@/ui/Section';
import { Select } from '@/ui/Select';
import { Table, TableBody, TableCell, TableHead, TableRow } from '@/ui/Table';
import { Group } from '@/ui/Group';
import { Text } from '@/ui/Text';
import { Award, ChevronLeft, Users } from 'lucide-react';

View File

@@ -1,5 +1,7 @@
import { TemplateProps } from '@/lib/contracts/components/ComponentContracts';
import { Carousel } from '@/components/shared/Carousel';
import { TeamCard } from '@/components/teams/TeamCard';
import { TeamSearchBar } from '@/components/teams/TeamSearchBar';