From 41e21e6595de152bc5536ad4bdcb38e85fbdd664 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Mon, 19 Jan 2026 18:34:01 +0100 Subject: [PATCH] website refactor --- .../client-wrapper/AdminUsersWrapper.tsx | 4 +- .../LeagueAdminSchedulePageClient.tsx | 29 +- .../ProfileSettingsPageClient.tsx | 36 +- .../SponsorshipRequestsClient.tsx | 36 +- apps/website/components/app/AppFooter.tsx | 2 +- .../leagues/CreateLeagueWizardLayout.tsx | 8 +- .../components/shared/SharedEmptyState.tsx | 26 - .../components/shared/UIComponents.tsx | 44 -- apps/website/templates/AdminUsersTemplate.tsx | 40 +- apps/website/templates/DashboardTemplate.tsx | 26 +- .../templates/LeagueDetailTemplate.tsx | 44 +- apps/website/templates/MediaTemplate.tsx | 15 +- .../templates/ProfileLiveryUploadTemplate.tsx | 68 ++- apps/website/templates/ProfileTemplate.tsx | 8 +- .../templates/ProtestDetailTemplate.tsx | 526 +++++++++--------- apps/website/templates/RacesAllTemplate.tsx | 12 +- .../templates/SponsorLeagueDetailTemplate.tsx | 290 +++++----- apps/website/templates/StewardingTemplate.tsx | 60 +- apps/website/templates/auth/LoginTemplate.tsx | 14 +- .../website/templates/auth/SignupTemplate.tsx | 26 +- .../templates/layout/GlobalFooterTemplate.tsx | 4 +- .../layout/GlobalSidebarTemplate.tsx | 2 +- .../layout/HeaderContentTemplate.tsx | 12 +- .../templates/shared/StatusTemplates.tsx | 28 +- 24 files changed, 643 insertions(+), 717 deletions(-) delete mode 100644 apps/website/components/shared/SharedEmptyState.tsx delete mode 100644 apps/website/components/shared/UIComponents.tsx diff --git a/apps/website/client-wrapper/AdminUsersWrapper.tsx b/apps/website/client-wrapper/AdminUsersWrapper.tsx index de8ece58b..78df4c96d 100644 --- a/apps/website/client-wrapper/AdminUsersWrapper.tsx +++ b/apps/website/client-wrapper/AdminUsersWrapper.tsx @@ -6,7 +6,7 @@ import { AdminUsersTemplate } from '@/templates/AdminUsersTemplate'; import { AdminUsersViewData } from '@/lib/view-data/AdminUsersViewData'; import { updateUserStatus, deleteUser } from '@/app/actions/adminActions'; import { routes } from '@/lib/routing/RouteConfig'; -import { SharedConfirmDialog } from '@/components/shared/UIComponents'; +import { ConfirmDialog } from '@/components/shared/ConfirmDialog'; import { ClientWrapperProps } from '@/lib/contracts/components/ComponentContracts'; export function AdminUsersWrapper({ viewData }: ClientWrapperProps) { @@ -148,7 +148,7 @@ export function AdminUsersWrapper({ viewData }: ClientWrapperProps - setUserToDelete(null)} onConfirm={confirmDeleteUser} diff --git a/apps/website/client-wrapper/LeagueAdminSchedulePageClient.tsx b/apps/website/client-wrapper/LeagueAdminSchedulePageClient.tsx index 1e78d192b..aabb8fce8 100644 --- a/apps/website/client-wrapper/LeagueAdminSchedulePageClient.tsx +++ b/apps/website/client-wrapper/LeagueAdminSchedulePageClient.tsx @@ -8,7 +8,12 @@ import { updateRaceAction } from '@/app/actions/leagueScheduleActions'; import { StatefulPageWrapper } from '@/components/shared/state/StatefulPageWrapper'; -import { SharedConfirmDialog, SharedStack, SharedCard, SharedBox, SharedText, SharedHeading } from '@/components/shared/UIComponents'; +import { ConfirmDialog } from '@/components/shared/ConfirmDialog'; +import { Stack } from '@/ui/Stack'; +import { Card } from '@/ui/Card'; +import { Box } from '@/ui/Box'; +import { Text } from '@/ui/Text'; +import { Heading } from '@/ui/Heading'; import { useLeagueAdminSchedule, useLeagueAdminStatus, @@ -172,16 +177,16 @@ export function LeagueAdminSchedulePageClient() { // Render admin access required if not admin if (!isLoading && !isAdmin) { return ( - - - - Admin Access Required - - Only league admins can manage the schedule. - - - - + + + + Admin Access Required + + Only league admins can manage the schedule. + + + + ); } @@ -221,7 +226,7 @@ export function LeagueAdminSchedulePageClient() { setForm(new RaceScheduleCommandModel(form.toCommand())); }} /> - setRaceToDelete(null)} onConfirm={confirmDelete} diff --git a/apps/website/client-wrapper/ProfileSettingsPageClient.tsx b/apps/website/client-wrapper/ProfileSettingsPageClient.tsx index bdb369458..7283638bb 100644 --- a/apps/website/client-wrapper/ProfileSettingsPageClient.tsx +++ b/apps/website/client-wrapper/ProfileSettingsPageClient.tsx @@ -3,13 +3,11 @@ import type { Result } from '@/lib/contracts/Result'; import type { ProfileViewData } from '@/lib/view-data/ProfileViewData'; import { ProfileSettingsTemplate } from '@/templates/ProfileSettingsTemplate'; -import { - SharedBox, - SharedStack, - SharedText, - SharedIcon, - SharedProgressLine -} from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Stack } from '@/ui/Stack'; +import { Text } from '@/ui/Text'; +import { Icon } from '@/ui/Icon'; +import { ProgressLine } from '@/components/shared/ProgressLine'; import { ShieldAlert } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; @@ -46,19 +44,19 @@ export function ProfileSettingsPageClient({ viewData, onSave }: ProfileSettingsP return ( <> - + {error && ( - - - - - - Update Failed - {error} - - - - + + + + + + Update Failed + {error} + + + + )} - + {error && ( - - - - - - Action Failed - {error} - - - - + + + + + + Action Failed + {error} + + + + )} {children ? ( diff --git a/apps/website/components/leagues/CreateLeagueWizardLayout.tsx b/apps/website/components/leagues/CreateLeagueWizardLayout.tsx index c2d67264c..118b0e794 100644 --- a/apps/website/components/leagues/CreateLeagueWizardLayout.tsx +++ b/apps/website/components/leagues/CreateLeagueWizardLayout.tsx @@ -1,7 +1,9 @@ 'use client'; import { ReactNode } from 'react'; -import { SharedBox, SharedStack, SharedContainer } from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Stack } from '@/ui/Stack'; +import { Container } from '@/ui/Container'; interface CreateLeagueWizardLayoutProps { children: ReactNode; @@ -13,12 +15,12 @@ interface CreateLeagueWizardLayoutProps { export function CreateLeagueWizardLayout({ children, header, progress, navigation, footer }: CreateLeagueWizardLayoutProps) { return ( - + {header} {progress} {children} {navigation} {footer} - + ); } diff --git a/apps/website/components/shared/SharedEmptyState.tsx b/apps/website/components/shared/SharedEmptyState.tsx deleted file mode 100644 index 13217594c..000000000 --- a/apps/website/components/shared/SharedEmptyState.tsx +++ /dev/null @@ -1,26 +0,0 @@ -'use client'; - -import { LucideIcon } from 'lucide-react'; -import { EmptyState } from '@/ui/EmptyState'; - -interface SharedEmptyStateProps { - icon: LucideIcon; - title: string; - description?: string; - action?: { - label: string; - onClick: () => void; - variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'race-final' | 'discord'; - }; -} - -export function SharedEmptyState({ icon, title, description, action }: SharedEmptyStateProps) { - return ( - - ); -} diff --git a/apps/website/components/shared/UIComponents.tsx b/apps/website/components/shared/UIComponents.tsx deleted file mode 100644 index 9adb23d59..000000000 --- a/apps/website/components/shared/UIComponents.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Pagination } from '@/ui/Pagination'; -import { Text } from '@/ui/Text'; -import { Box } from '@/ui/Box'; -import { Stack } from '@/ui/Stack'; -import { Container } from '@/ui/Container'; -import { ConfirmDialog } from '@/components/shared/ConfirmDialog'; -import { Button } from '@/ui/Button'; -import { Icon } from '@/ui/Icon'; -import { Card } from '@/ui/Card'; -import { Heading } from '@/ui/Heading'; -import { Grid } from '@/ui/Grid'; -import { GridItem } from '@/ui/GridItem'; -import { Surface } from '@/ui/Surface'; -import { Input } from '@/ui/Input'; -import { Link } from '@/ui/Link'; -import { Skeleton } from '@/ui/Skeleton'; -import { LoadingSpinner } from '@/ui/LoadingSpinner'; -import { Badge } from '@/ui/Badge'; - -import { ProgressLine } from '@/components/shared/ProgressLine'; -import { SharedEmptyState } from './SharedEmptyState'; - -export { - Pagination as SharedPagination, - Text as SharedText, - Box as SharedBox, - Stack as SharedStack, - Container as SharedContainer, - ConfirmDialog as SharedConfirmDialog, - Button as SharedButton, - Icon as SharedIcon, - Card as SharedCard, - Heading as SharedHeading, - Grid as SharedGrid, - GridItem as SharedGridItem, - Surface as SharedSurface, - Input as SharedInput, - Link as SharedLink, - Skeleton as SharedSkeleton, - LoadingSpinner as SharedLoadingSpinner, - Badge as SharedBadge, - ProgressLine as SharedProgressLine, - SharedEmptyState -}; diff --git a/apps/website/templates/AdminUsersTemplate.tsx b/apps/website/templates/AdminUsersTemplate.tsx index 7f7855e4e..3c5c408ae 100644 --- a/apps/website/templates/AdminUsersTemplate.tsx +++ b/apps/website/templates/AdminUsersTemplate.tsx @@ -8,7 +8,13 @@ import { AdminUsersTable } from '@/components/admin/AdminUsersTable'; import { BulkActionBar } from '@/components/admin/BulkActionBar'; import { UserFilters } from '@/components/admin/UserFilters'; import { AdminUsersViewData } from '@/lib/view-data/AdminUsersViewData'; -import { SharedButton, SharedContainer, SharedIcon, SharedStack, SharedBox, SharedText } from '@/components/shared/UIComponents'; +import { Button } from '@/ui/Button'; +import { Container } from '@/ui/Container'; +import { Icon } from '@/ui/Icon'; +import { Stack } from '@/ui/Stack'; +import { Box } from '@/ui/Box'; +import { Text } from '@/ui/Text'; +import { ErrorBanner } from '@/ui/ErrorBanner'; import { RefreshCw, ShieldAlert, Users } from 'lucide-react'; import { TemplateProps } from '@/lib/contracts/components/ComponentContracts'; @@ -95,37 +101,29 @@ export function AdminUsersTemplate({ ]; return ( - - - + + + } + icon={} > Refresh Data - + } /> {/* error notice should be a component */} {error && ( - - - - - Operation Failed - {error} - - - + )} @@ -147,9 +145,9 @@ export function AdminUsersTemplate({ title="No users found" description="Try adjusting your filters or search query" action={ - + } /> ) : ( @@ -170,8 +168,8 @@ export function AdminUsersTemplate({ actions={bulkActions} onClearSelection={onClearSelection} /> - - - + + + ); } diff --git a/apps/website/templates/DashboardTemplate.tsx b/apps/website/templates/DashboardTemplate.tsx index 2a5d7ae85..5b32005b8 100644 --- a/apps/website/templates/DashboardTemplate.tsx +++ b/apps/website/templates/DashboardTemplate.tsx @@ -67,14 +67,14 @@ export function DashboardTemplate({ - Next Event + Next Event {nextRace.track} - {nextRace.car} + {nextRace.car} - Starts In - {nextRace.timeUntil} - {nextRace.formattedDate} @ {nextRace.formattedTime} + Starts In + {nextRace.timeUntil} + {nextRace.formattedDate} @ {nextRace.formattedTime} @@ -85,7 +85,7 @@ export function DashboardTemplate({ ) : ( - No recent activity recorded. + No recent activity recorded. )} @@ -99,18 +99,18 @@ export function DashboardTemplate({ {hasLeagueStandings ? ( {leagueStandings.map((standing) => ( - + {standing.leagueName} - Pos: {standing.position} / {standing.totalDrivers} + Pos: {standing.position} / {standing.totalDrivers} - {standing.points} PTS + {standing.points} PTS ))} ) : ( - No active championships. + No active championships. )} @@ -121,11 +121,11 @@ export function DashboardTemplate({ {race.track} - {race.timeUntil} + {race.timeUntil} - {race.car} - {race.formattedDate} + {race.car} + {race.formattedDate} ))} diff --git a/apps/website/templates/LeagueDetailTemplate.tsx b/apps/website/templates/LeagueDetailTemplate.tsx index eaa90903d..a547337e5 100644 --- a/apps/website/templates/LeagueDetailTemplate.tsx +++ b/apps/website/templates/LeagueDetailTemplate.tsx @@ -3,35 +3,33 @@ import { LeagueCard } from '@/components/leagues/LeagueCardWrapper'; import { routes } from '@/lib/routing/RouteConfig'; import type { LeagueDetailViewData } from '@/lib/view-data/LeagueDetailViewData'; -import { - SharedBox, - SharedLink, - SharedText, - SharedStack, - SharedContainer, - SharedIcon -} from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Link } from '@/ui/Link'; +import { Text } from '@/ui/Text'; +import { Stack } from '@/ui/Stack'; +import { Container } from '@/ui/Container'; +import { Icon } from '@/ui/Icon'; import { ChevronRight } from 'lucide-react'; import { TemplateProps } from '@/lib/contracts/components/ComponentContracts'; export function LeagueDetailTemplate({ viewData, children, tabs }: TemplateProps & { children?: React.ReactNode, tabs?: any[] }) { return ( - - - - - - - Leagues - - - {viewData.name} - - + + + + + + + Leagues + + + {viewData.name} + + {children} {/* ... rest of the template ... */} - - - + + + ); } diff --git a/apps/website/templates/MediaTemplate.tsx b/apps/website/templates/MediaTemplate.tsx index bf685a5ea..8182ad05b 100644 --- a/apps/website/templates/MediaTemplate.tsx +++ b/apps/website/templates/MediaTemplate.tsx @@ -2,24 +2,25 @@ import { MediaGallery } from '@/components/media/MediaGallery'; import { MediaViewData } from '@/lib/view-data/MediaViewData'; -import { SharedBox, SharedContainer } from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Container } from '@/ui/Container'; import { TemplateProps } from '@/lib/contracts/components/ComponentContracts'; export function MediaTemplate({ viewData }: TemplateProps) { const { assets, categories, title, description } = viewData; return ( - - - + + + - - - + + + ); } diff --git a/apps/website/templates/ProfileLiveryUploadTemplate.tsx b/apps/website/templates/ProfileLiveryUploadTemplate.tsx index 369610587..417f9e187 100644 --- a/apps/website/templates/ProfileLiveryUploadTemplate.tsx +++ b/apps/website/templates/ProfileLiveryUploadTemplate.tsx @@ -2,14 +2,12 @@ import { UploadDropzone } from '@/components/shared/UploadDropzone'; import { routes } from '@/lib/routing/RouteConfig'; -import { - SharedBox, - SharedButton, - SharedStack, - SharedText, - SharedContainer, - SharedCard -} from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Button } from '@/ui/Button'; +import { Stack } from '@/ui/Stack'; +import { Text } from '@/ui/Text'; +import { Container } from '@/ui/Container'; +import { Card } from '@/ui/Card'; import { Heading } from '@/ui/Heading'; import { MediaMetaPanel, mapMediaMetadata } from '@/ui/MediaMetaPanel'; import { MediaPreviewCard } from '@/ui/MediaPreviewCard'; @@ -33,18 +31,18 @@ export function ProfileLiveryUploadTemplate({ onUpload, }: ProfileLiveryUploadTemplateProps) { return ( - - - + + + Upload livery - + Upload your custom car livery. Supported formats: .png, .jpg, .tga - - + + - - - + + + - + - Cancel + - Upload Livery - - - - + + + + - + {previewUrl ? ( - + - + ) : ( - - + + Select a file to see preview and details - - + + )} - - - - + + + + ); } diff --git a/apps/website/templates/ProfileTemplate.tsx b/apps/website/templates/ProfileTemplate.tsx index c412dbbba..a3d5e9811 100644 --- a/apps/website/templates/ProfileTemplate.tsx +++ b/apps/website/templates/ProfileTemplate.tsx @@ -39,11 +39,11 @@ export function ProfileTemplate({ return ( - + Create Your Driver Profile - Join the GridPilot community and start your racing journey + Join the GridPilot community and start your racing journey @@ -51,7 +51,7 @@ export function ProfileTemplate({ Get Started - + Create your driver profile to join leagues, compete in races, and connect with other drivers. @@ -110,7 +110,7 @@ export function ProfileTemplate({ Achievements - {viewData.extendedProfile.achievements.length} earned + {viewData.extendedProfile.achievements.length} earned ({ diff --git a/apps/website/templates/ProtestDetailTemplate.tsx b/apps/website/templates/ProtestDetailTemplate.tsx index 00bc005a1..45246d89b 100644 --- a/apps/website/templates/ProtestDetailTemplate.tsx +++ b/apps/website/templates/ProtestDetailTemplate.tsx @@ -1,14 +1,12 @@ 'use client'; -import { - SharedBox, - SharedButton, - SharedStack, - SharedText, - SharedIcon, - SharedCard, - SharedContainer -} from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Button } from '@/ui/Button'; +import { Stack } from '@/ui/Stack'; +import { Text } from '@/ui/Text'; +import { Icon } from '@/ui/Icon'; +import { Card } from '@/ui/Card'; +import { Container } from '@/ui/Container'; import { Heading } from '@/ui/Heading'; import { Link as UILink } from '@/ui/Link'; import { Grid } from '@/ui/Grid'; @@ -99,114 +97,114 @@ export function ProtestDetailTemplate({ const daysSinceFiled = Math.floor((Date.now() - new Date(submittedAt).getTime()) / (1000 * 60 * 60 * 24)); return ( - - - + + + {/* Compact Header */} - - + + - + - + Protest Review - - - {statusConfig.label} - + + + {statusConfig.label} + {daysSinceFiled > 2 && isPending && ( - - - {daysSinceFiled}d old - + + + {daysSinceFiled}d old + )} - - - + + + {/* Main Layout: Feed + Sidebar */} {/* Left Sidebar - Incident Info */} - + {/* Drivers Involved */} - - + + Parties Involved - + {/* Protesting Driver */} - - - - - - Protesting - {protestingDriver?.name || 'Unknown'} - - - + + + + + + Protesting + {protestingDriver?.name || 'Unknown'} + + + {/* Accused Driver */} - - - - - - Accused - {accusedDriver?.name || 'Unknown'} - - - + + + + + + Accused + {accusedDriver?.name || 'Unknown'} + + + - - - + + + {/* Race Info */} - - + + Race Details - + - - - {race?.name || 'Unknown Race'} - - - + + + {race?.name || 'Unknown Race'} + + + - + - - - - {race?.name || 'Unknown Track'} - - - - {race?.formattedDate || (race?.scheduledAt ? new Date(race.scheduledAt).toLocaleDateString() : 'Unknown Date')} - + + + + {race?.name || 'Unknown Track'} + + + + {race?.formattedDate || (race?.scheduledAt ? new Date(race.scheduledAt).toLocaleDateString() : 'Unknown Date')} + {protest.incident?.lap && ( - - - Lap {protest.incident.lap} - + + + Lap {protest.incident.lap} + )} - - - + + + {protest.proofVideoUrl && ( - - + + Evidence - - - Watch Video - - + + + Watch Video + + - - + + )} {/* Quick Stats */} - - + + Timeline - - - Filed - {new Date(submittedAt).toLocaleDateString()} - - - Age - 2 ? 'text-red-400' : 'text-gray-300'}>{daysSinceFiled} days - + + + Filed + {new Date(submittedAt).toLocaleDateString()} + + + Age + 2 ? 'text-red-400' : 'text-gray-300'}>{daysSinceFiled} days + {protest.reviewedAt && ( - - Resolved - {new Date(protest.reviewedAt).toLocaleDateString()} - + + Resolved + {new Date(protest.reviewedAt).toLocaleDateString()} + )} - - - - + + + + {/* Center - Discussion Feed */} - + {/* Timeline / Feed */} - - + + Discussion - + - + {/* Initial Protest Filing */} - - - - - - - - {protestingDriver?.name || 'Unknown'} - filed protest - - {new Date(submittedAt).toLocaleString()} - + + + + + + + + {protestingDriver?.name || 'Unknown'} + filed protest + + {new Date(submittedAt).toLocaleString()} + - - {protest.description || protestDetail.incident?.description} + + {protest.description || protestDetail.incident?.description} {(protest.comment || protestDetail.comment) && ( - - Additional details: - {protest.comment || protestDetail.comment} - + + Additional details: + {protest.comment || protestDetail.comment} + )} - - - - + + + + {/* Defense placeholder */} {protest.status === 'awaiting_defense' && ( - - - - - - - Defense Requested - Waiting for {accusedDriver?.name || 'the accused driver'} to submit their defense... - - - + + + + + + + Defense Requested + Waiting for {accusedDriver?.name || 'the accused driver'} to submit their defense... + + + )} {/* Decision (if resolved) */} {(protest.status === 'upheld' || protest.status === 'dismissed') && protest.decisionNotes && ( - - - - - - - - Steward Decision - + + + + + + + + Steward Decision + {protest.status === 'upheld' ? 'Protest Upheld' : 'Protest Dismissed'} - + {protest.reviewedAt && ( <> - - {new Date(protest.reviewedAt).toLocaleString()} + + {new Date(protest.reviewedAt).toLocaleString()} )} - + - - {protest.decisionNotes} - - - - + + {protest.decisionNotes} + + + + )} - + {/* Add Comment */} {isPending && ( - - - - - - - + + + + + + ) => setNewComment(e.target.value)} placeholder="Add a comment or request more information..." @@ -355,102 +353,102 @@ export function ProtestDetailTemplate({ color="text-white" fontSize="sm" /> - - - + + + + + + )} - - + + {/* Right Sidebar - Actions */} - + {isPending && ( <> {/* Quick Actions */} - - + + Actions - - + - setShowDecisionPanel(!showDecisionPanel)} > - - - Make Decision - - - - - - - - + + + Make Decision + + + + + + + + {/* Decision Panel */} {showDecisionPanel && ( - - + + Stewarding Decision {/* Decision Selection */} - - + + + + + {/* Penalty Selection (if upholding) */} {decision === 'uphold' && ( - - Penalty Type + + Penalty Type {penaltyTypes.length === 0 ? ( - + Loading penalty types... - + ) : ( <> @@ -458,8 +456,8 @@ export function ProtestDetailTemplate({ const Icon = penalty.icon; const isSelected = penaltyType === penalty.type; return ( - - + + ); })} {selectedPenalty?.requiresValue && ( - - + + Value ({selectedPenalty.valueLabel}) - - + ) => setPenaltyValue(Number(e.target.value))} @@ -500,17 +498,17 @@ export function ProtestDetailTemplate({ color="text-white" fontSize="sm" /> - + )} )} - + )} {/* Steward Notes */} - - Decision Reasoning * - + Decision Reasoning * + ) => setStewardNotes(e.target.value)} placeholder="Explain your decision..." @@ -525,42 +523,42 @@ export function ProtestDetailTemplate({ color="text-white" fontSize="sm" /> - + {/* Submit */} - {submitting ? 'Submitting...' : 'Submit Decision'} - - - + + + )} )} {/* Already Resolved Info */} {!isPending && ( - - - - - Case Closed - + + + + + Case Closed + {protest.status === 'upheld' ? 'Protest was upheld' : 'Protest was dismissed'} - - - - + + + + )} - + - - - + + + ); } diff --git a/apps/website/templates/RacesAllTemplate.tsx b/apps/website/templates/RacesAllTemplate.tsx index f14c07c4b..2cc2c6f17 100644 --- a/apps/website/templates/RacesAllTemplate.tsx +++ b/apps/website/templates/RacesAllTemplate.tsx @@ -7,7 +7,9 @@ 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 { SharedPagination, SharedText, SharedBox } from '@/components/shared/UIComponents'; +import { Pagination } from '@/ui/Pagination'; +import { Text } from '@/ui/Text'; +import { Box } from '@/ui/Box'; import { TemplateProps } from '@/lib/contracts/components/ComponentContracts'; export type StatusFilter = 'scheduled' | 'running' | 'completed' | 'cancelled' | 'all'; @@ -76,7 +78,7 @@ export function RacesAllTemplate({ /> } pagination={ - {races.length === 0 ? ( - - No races found matching your criteria. - + + No races found matching your criteria. + ) : ( ({ diff --git a/apps/website/templates/SponsorLeagueDetailTemplate.tsx b/apps/website/templates/SponsorLeagueDetailTemplate.tsx index d6cd7ec3f..4b85a5b16 100644 --- a/apps/website/templates/SponsorLeagueDetailTemplate.tsx +++ b/apps/website/templates/SponsorLeagueDetailTemplate.tsx @@ -7,15 +7,13 @@ import { SponsorDashboardHeader } from '@/components/sponsors/SponsorDashboardHe import { SponsorStatusChip } from '@/components/sponsors/SponsorStatusChip'; import { routes } from '@/lib/routing/RouteConfig'; import { siteConfig } from '@/lib/siteConfig'; -import { - SharedBox, - SharedButton, - SharedStack, - SharedText, - SharedIcon, - SharedCard, - SharedContainer -} from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Button } from '@/ui/Button'; +import { Stack } from '@/ui/Stack'; +import { Text } from '@/ui/Text'; +import { Icon } from '@/ui/Icon'; +import { Card } from '@/ui/Card'; +import { Container } from '@/ui/Container'; import { Heading } from '@/ui/Heading'; import { Link } from '@/ui/Link'; import { Grid } from '@/ui/Grid'; @@ -187,23 +185,23 @@ export function SponsorLeagueDetailTemplate({ ]; return ( - - - + + + {/* Breadcrumb */} - - + + - Dashboard + Dashboard - / + / - Leagues + Leagues - / - {league.name} - - + / + {league.name} + + {/* Header */} {/* Tabs */} - - + + {(['overview', 'drivers', 'races', 'sponsor'] as const).map((tab) => ( - setActiveTab(tab)} style={{ paddingBottom: '0.75rem' }} @@ -227,148 +225,148 @@ export function SponsorLeagueDetailTemplate({ borderColor={activeTab === tab ? 'border-primary-blue' : 'border-transparent'} color={activeTab === tab ? 'text-primary-blue' : 'text-gray-400'} > - + {tab === 'sponsor' ? '🎯 Become a Sponsor' : tab} - - + + ))} - - + + {/* Tab Content */} {activeTab === 'overview' && ( - - - - + + + + League Information - - - + + + - - + + - - - }> + + + }> Sponsorship Value - - + + - - + + {league.nextRace && ( - - - }> + + + }> Next Race - + - - + + - + - - {league.nextRace.name} - {league.nextRace.formattedDate} - - - + + {league.nextRace.name} + {league.nextRace.formattedDate} + + + + - + )} )} {activeTab === 'drivers' && ( - - + + Championship Standings - Top drivers carrying sponsor branding - - + Top drivers carrying sponsor branding + + {viewData.drivers.map((driver, index) => ( - - - + + + - {driver.positionLabel} + {driver.positionLabel} - - {driver.name} - {driver.team} • {driver.country} - - - - - {driver.formattedRaces} - races - - - {driver.formattedImpressions} - views - - - - + + {driver.name} + {driver.team} • {driver.country} + + + + + {driver.formattedRaces} + races + + + {driver.formattedImpressions} + views + + + + ))} - - + + )} {activeTab === 'races' && ( - - + + Race Calendar - Season schedule with view statistics - - + Season schedule with view statistics + + {viewData.races.map((race, index) => ( - - - - - - {race.name} - {race.formattedDate} - - - + + + + + + {race.name} + {race.formattedDate} + + + {race.status === 'completed' ? ( - - {race.formattedViews} - views - + + {race.formattedViews} + views + ) : ( )} - - - + + + ))} - - + + )} {activeTab === 'sponsor' && ( @@ -383,62 +381,62 @@ export function SponsorLeagueDetailTemplate({ - + - - - }> + + + }> Sponsorship Summary - + - + - - - Total (excl. VAT) - + + + Total (excl. VAT) + ${((selectedTier === 'main' ? league.sponsorSlots.main.price : league.sponsorSlots.secondary.price) * (1 + siteConfig.fees.platformFeePercent / 100)).toFixed(2)} - - - - + + + + - + {siteConfig.vat.notice} - + - - }> + + + + + + )} - - - + + + ); } function InfoRow({ label, value, color = 'text-white', last }: { label: string, value: string | number, color?: string, last?: boolean }) { return ( - - - {label} - {value} - - + + + {label} + {value} + + ); } diff --git a/apps/website/templates/StewardingTemplate.tsx b/apps/website/templates/StewardingTemplate.tsx index 30bb7ecc2..93fd90ec3 100644 --- a/apps/website/templates/StewardingTemplate.tsx +++ b/apps/website/templates/StewardingTemplate.tsx @@ -7,13 +7,11 @@ import { StewardingQueuePanel } from '@/components/leagues/StewardingQueuePanel' import { StewardingStats } from '@/components/leagues/StewardingStats'; import { PenaltyFAB } from '@/components/races/PenaltyFAB'; import type { StewardingViewData } from '@/lib/view-data/leagues/StewardingViewData'; -import { - SharedBox, - SharedButton, - SharedStack, - SharedText, - SharedCard -} from '@/components/shared/UIComponents'; +import { Box } from '@/ui/Box'; +import { Button } from '@/ui/Button'; +import { Stack } from '@/ui/Stack'; +import { Text } from '@/ui/Text'; +import { Card } from '@/ui/Card'; import { TemplateProps } from '@/lib/contracts/components/ComponentContracts'; interface StewardingTemplateProps extends TemplateProps { @@ -51,7 +49,7 @@ export function StewardingTemplate({ currentDriverId, }: StewardingTemplateProps) { return ( - + {/* Tab navigation */} - - - + + - onTabChange('pending')} rounded={false} > - - Pending Protests + + Pending Protests {viewData.totalPending > 0 && ( - + {viewData.totalPending} - + )} - - - - + + + - onTabChange('history')} rounded={false} > - History - - - - + History + + + + {/* Content */} {activeTab === 'pending' ? ( @@ -102,15 +100,15 @@ export function StewardingTemplate({ onReview={onReviewProtest} /> ) : ( - - + + - - + + )} {activeTab === 'history' && ( @@ -141,6 +139,6 @@ export function StewardingTemplate({ races={viewData.races.map(r => ({ id: r.id, track: r.track, scheduledAt: new Date(r.scheduledAt) }))} /> )} - + ); } diff --git a/apps/website/templates/auth/LoginTemplate.tsx b/apps/website/templates/auth/LoginTemplate.tsx index e573fb4d3..2900fc9ef 100644 --- a/apps/website/templates/auth/LoginTemplate.tsx +++ b/apps/website/templates/auth/LoginTemplate.tsx @@ -74,7 +74,7 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem /> - + Forgot password? @@ -101,10 +101,10 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem {viewData.hasInsufficientPermissions && ( - + - Insufficient Permissions - + Insufficient Permissions + Please log in with an account that has the required role. @@ -133,17 +133,17 @@ export function LoginTemplate({ viewData, formActions, mutationState }: LoginTem - + Don't have an account?{' '} - Create one + Create one - + By signing in, you agree to our{' '} Terms {' '}and{' '} diff --git a/apps/website/templates/auth/SignupTemplate.tsx b/apps/website/templates/auth/SignupTemplate.tsx index 1bb0ae215..7ecd519e4 100644 --- a/apps/website/templates/auth/SignupTemplate.tsx +++ b/apps/website/templates/auth/SignupTemplate.tsx @@ -62,7 +62,7 @@ export function SignupTemplate({ viewData, formActions, uiState, mutationState } - Personal Information + Personal Information - - - Note: Your name cannot be changed after signup. + + + Note: Your name cannot be changed after signup. @@ -113,7 +113,7 @@ export function SignupTemplate({ viewData, formActions, uiState, mutationState } - Security + Security - + {passwordStrength.label} {passwordRequirements.map((req, index) => ( - - + + {req.label} @@ -173,8 +173,8 @@ export function SignupTemplate({ viewData, formActions, uiState, mutationState } {mutationState.error && ( - - {mutationState.error} + + {mutationState.error} )} @@ -190,17 +190,17 @@ export function SignupTemplate({ viewData, formActions, uiState, mutationState } - + Already have an account?{' '} - Sign in + Sign in - + By creating an account, you agree to our{' '} Terms {' '}and{' '} diff --git a/apps/website/templates/layout/GlobalFooterTemplate.tsx b/apps/website/templates/layout/GlobalFooterTemplate.tsx index b8d98e831..cfdd14b19 100644 --- a/apps/website/templates/layout/GlobalFooterTemplate.tsx +++ b/apps/website/templates/layout/GlobalFooterTemplate.tsx @@ -15,8 +15,8 @@ export function GlobalFooterTemplate(_props: GlobalFooterViewData) { - - + + INFRASTRUCTURE diff --git a/apps/website/templates/layout/GlobalSidebarTemplate.tsx b/apps/website/templates/layout/GlobalSidebarTemplate.tsx index 3af6e840a..4c420df70 100644 --- a/apps/website/templates/layout/GlobalSidebarTemplate.tsx +++ b/apps/website/templates/layout/GlobalSidebarTemplate.tsx @@ -21,7 +21,7 @@ export function GlobalSidebarTemplate(_props: GlobalSidebarViewData) { - + NAVIGATION diff --git a/apps/website/templates/layout/HeaderContentTemplate.tsx b/apps/website/templates/layout/HeaderContentTemplate.tsx index ff1111958..205be0a4d 100644 --- a/apps/website/templates/layout/HeaderContentTemplate.tsx +++ b/apps/website/templates/layout/HeaderContentTemplate.tsx @@ -20,9 +20,9 @@ export function HeaderContentTemplate(_props: HeaderContentViewData) { <> - - - + + + MOTORSPORT INFRASTRUCTURE @@ -35,9 +35,9 @@ export function HeaderContentTemplate(_props: HeaderContentViewData) { )} - - STATUS: - OPERATIONAL + + STATUS: + OPERATIONAL diff --git a/apps/website/templates/shared/StatusTemplates.tsx b/apps/website/templates/shared/StatusTemplates.tsx index 27026d0cf..10d63f3fa 100644 --- a/apps/website/templates/shared/StatusTemplates.tsx +++ b/apps/website/templates/shared/StatusTemplates.tsx @@ -1,6 +1,8 @@ 'use client'; -import { SharedContainer, SharedStack, SharedText } from '@/components/shared/UIComponents'; +import { Container } from '@/ui/Container'; +import { Stack } from '@/ui/Stack'; +import { Text } from '@/ui/Text'; import { TemplateProps } from '@/lib/contracts/components/ComponentContracts'; import { ViewData } from '@/lib/contracts/view-data/ViewData'; @@ -11,12 +13,12 @@ interface ErrorTemplateProps extends TemplateProps { export function ErrorTemplate({ message = "An error occurred", description = "Please try again later" }: ErrorTemplateProps) { return ( - - - {message} - {description} - - + + + {message} + {description} + + ); } @@ -27,11 +29,11 @@ interface EmptyTemplateProps extends TemplateProps { export function EmptyTemplate({ title, description }: EmptyTemplateProps) { return ( - - - {title} - {description} - - + + + {title} + {description} + + ); }