diff --git a/apps/website/app/leagues/[id]/layout.tsx b/apps/website/app/leagues/[id]/layout.tsx index b868e3436..d076975f9 100644 --- a/apps/website/app/leagues/[id]/layout.tsx +++ b/apps/website/app/leagues/[id]/layout.tsx @@ -1,12 +1,12 @@ 'use client'; -import React, { useState, useEffect } from 'react'; -import { useParams, usePathname, useRouter } from 'next/navigation'; import Breadcrumbs from '@/components/layout/Breadcrumbs'; import LeagueHeader from '@/components/leagues/LeagueHeader'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import type { League } from '@core/racing/domain/entities/League'; +import { useParams, usePathname, useRouter } from 'next/navigation'; +import React, { useEffect, useState } from 'react'; // Main sponsor info for "by XYZ" display interface MainSponsorInfo { diff --git a/apps/website/app/leagues/[id]/page.tsx b/apps/website/app/leagues/[id]/page.tsx index 2dd816f58..31ee97cfb 100644 --- a/apps/website/app/leagues/[id]/page.tsx +++ b/apps/website/app/leagues/[id]/page.tsx @@ -1,33 +1,32 @@ 'use client'; -import { useState, useEffect, useMemo } from 'react'; -import { useRouter, useParams } from 'next/navigation'; -import Button from '@/components/ui/Button'; -import Card from '@/components/ui/Card'; +import DriverIdentity from '@/components/drivers/DriverIdentity'; +import EndRaceModal from '@/components/leagues/EndRaceModal'; import JoinLeagueButton from '@/components/leagues/JoinLeagueButton'; import LeagueActivityFeed from '@/components/leagues/LeagueActivityFeed'; -import EndRaceModal from '@/components/leagues/EndRaceModal'; -import DriverIdentity from '@/components/drivers/DriverIdentity'; -import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; import SponsorInsightsCard, { - useSponsorMode, MetricBuilders, SlotTemplates, + useSponsorMode, type SponsorMetric, } from '@/components/sponsors/SponsorInsightsCard'; +import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import { getLeagueMembers, getMembership } from '@/lib/leagueMembership'; +import { getLeagueRoleDisplay } from '@/lib/leagueRoles'; +import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter'; import { - League, Driver, EntityMappers, + League, + Race, type DriverDTO, type LeagueScoringConfigDTO, - Race, } from '@core/racing'; -import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter'; -import { Trophy, Star, ExternalLink, Calendar, Users } from 'lucide-react'; -import { getMembership, getLeagueMembers } from '@/lib/leagueMembership'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import { getLeagueRoleDisplay } from '@/lib/leagueRoles'; +import { Calendar, ExternalLink, Star, Trophy, Users } from 'lucide-react'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useMemo, useState } from 'react'; // Sponsor info type interface SponsorInfo { diff --git a/apps/website/app/leagues/[id]/schedule/page.tsx b/apps/website/app/leagues/[id]/schedule/page.tsx index 303dcc53d..737584436 100644 --- a/apps/website/app/leagues/[id]/schedule/page.tsx +++ b/apps/website/app/leagues/[id]/schedule/page.tsx @@ -1,13 +1,11 @@ 'use client'; -import { useParams } from 'next/navigation'; -import Card from '@/components/ui/Card'; import LeagueSchedule from '@/components/leagues/LeagueSchedule'; -import ScheduleRaceForm from '@/components/leagues/ScheduleRaceForm'; -import { useState, useEffect } from 'react'; -import { useRouter } from 'next/navigation'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; export default function LeagueSchedulePage() { const params = useParams(); diff --git a/apps/website/app/leagues/[id]/settings/page.tsx b/apps/website/app/leagues/[id]/settings/page.tsx index 6f35dd77a..8403a71f6 100644 --- a/apps/website/app/leagues/[id]/settings/page.tsx +++ b/apps/website/app/leagues/[id]/settings/page.tsx @@ -1,23 +1,21 @@ 'use client'; -import { useState, useEffect, useMemo } from 'react'; -import { useParams, useRouter } from 'next/navigation'; -import Card from '@/components/ui/Card'; +import { ReadonlyLeagueInfo } from '@/components/leagues/ReadonlyLeagueInfo'; +import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { LeagueFullConfigPresenter } from '@/lib/presenters/LeagueFullConfigPresenter'; import { LeagueScoringPresetsPresenter } from '@/lib/presenters/LeagueScoringPresetsPresenter'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; -import { ScoringPatternSection, ChampionshipsSection } from '@/components/leagues/LeagueScoringSection'; -import { LeagueDropSection } from '@/components/leagues/LeagueDropSection'; -import { ReadonlyLeagueInfo } from '@/components/leagues/ReadonlyLeagueInfo'; import type { LeagueConfigFormModel } from '@core/racing/application'; -import type { League } from '@core/racing/domain/entities/League'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; -import type { LeagueScoringPresetDTO } from '@core/racing/application/ports/LeagueScoringPresetProvider'; import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; -import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; -import { AlertTriangle, Settings, Trophy, Calendar, TrendingDown, Edit, Users, UserCog } from 'lucide-react'; +import type { LeagueScoringPresetDTO } from '@core/racing/application/ports/LeagueScoringPresetProvider'; +import type { League } from '@core/racing/domain/entities/League'; +import { AlertTriangle, Settings, UserCog } from 'lucide-react'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useMemo, useState } from 'react'; export default function LeagueSettingsPage() { const params = useParams(); diff --git a/apps/website/app/leagues/[id]/sponsorships/page.tsx b/apps/website/app/leagues/[id]/sponsorships/page.tsx index a5f7c9d25..3812561f1 100644 --- a/apps/website/app/leagues/[id]/sponsorships/page.tsx +++ b/apps/website/app/leagues/[id]/sponsorships/page.tsx @@ -1,14 +1,13 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { useParams } from 'next/navigation'; -import Card from '@/components/ui/Card'; -import Button from '@/components/ui/Button'; import { LeagueSponsorshipsSection } from '@/components/leagues/LeagueSponsorshipsSection'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; -import { AlertTriangle, Building, DollarSign } from 'lucide-react'; import type { League } from '@core/racing/domain/entities/League'; +import { AlertTriangle, Building } from 'lucide-react'; +import { useParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; export default function LeagueSponsorshipsPage() { const params = useParams(); diff --git a/apps/website/app/leagues/[id]/standings/page.tsx b/apps/website/app/leagues/[id]/standings/page.tsx index 5116bead2..86985c46f 100644 --- a/apps/website/app/leagues/[id]/standings/page.tsx +++ b/apps/website/app/leagues/[id]/standings/page.tsx @@ -1,16 +1,15 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; -import { useParams } from 'next/navigation'; -import Card from '@/components/ui/Card'; import StandingsTable from '@/components/leagues/StandingsTable'; -import { getLeagueStandings } from '@/lib/services/leagues/LeagueService'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import type { DriverDto, LeagueMembership } from '@/lib/dtos'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; +import { getLeagueStandings } from '@/lib/services/leagues/LeagueService'; import type { LeagueStandingsViewModel } from '@/lib/view-models'; import type { StandingEntryViewModel } from '@/lib/view-models/StandingEntryViewModel'; -import type { DriverDto } from '@/lib/dtos'; -import type { LeagueMembership } from '@/lib/dtos'; +import { useParams } from 'next/navigation'; +import { useCallback, useEffect, useState } from 'react'; export default function LeagueStandingsPage() { const params = useParams(); diff --git a/apps/website/app/leagues/[id]/stewarding/page.tsx b/apps/website/app/leagues/[id]/stewarding/page.tsx index 3c0148a8a..95f3202ce 100644 --- a/apps/website/app/leagues/[id]/stewarding/page.tsx +++ b/apps/website/app/leagues/[id]/stewarding/page.tsx @@ -1,24 +1,32 @@ 'use client'; -import { useState, useEffect, useMemo } from 'react'; -import { useParams } from 'next/navigation'; -import Link from 'next/link'; -import Card from '@/components/ui/Card'; -import Button from '@/components/ui/Button'; -import { ReviewProtestModal } from '@/components/leagues/ReviewProtestModal'; -import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal'; import PenaltyFAB from '@/components/leagues/PenaltyFAB'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal'; +import { ReviewProtestModal } from '@/components/leagues/ReviewProtestModal'; +import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; -import type { Protest } from '@core/racing/domain/entities/Protest'; -import type { Race } from '@core/racing/domain/entities/Race'; -import type { Penalty, PenaltyType } from '@core/racing/domain/entities/Penalty'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; +import type { Penalty, PenaltyType } from '@core/racing/domain/entities/Penalty'; +import type { Protest } from '@core/racing/domain/entities/Protest'; +import type { Race } from '@core/racing/domain/entities/Race'; import { - AlertTriangle, Clock, CheckCircle, Flag, ChevronRight, - Calendar, MapPin, AlertCircle, Video, Gavel + AlertCircle, + AlertTriangle, + Calendar, + CheckCircle, + ChevronRight, + Clock, + Flag, + Gavel, + MapPin, + Video } from 'lucide-react'; +import Link from 'next/link'; +import { useParams } from 'next/navigation'; +import { useEffect, useMemo, useState } from 'react'; interface RaceWithProtests { race: Race; diff --git a/apps/website/app/leagues/[id]/stewarding/protests/[protestId]/page.tsx b/apps/website/app/leagues/[id]/stewarding/protests/[protestId]/page.tsx index d5538cd56..e5b441e78 100644 --- a/apps/website/app/leagues/[id]/stewarding/protests/[protestId]/page.tsx +++ b/apps/website/app/leagues/[id]/stewarding/protests/[protestId]/page.tsx @@ -1,42 +1,39 @@ 'use client'; -import { useState, useEffect, useMemo } from 'react'; -import { useParams, useRouter } from 'next/navigation'; -import Link from 'next/link'; -import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; +import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; +import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; +import type { PenaltyType } from '@core/racing/domain/entities/Penalty'; import type { Protest } from '@core/racing/domain/entities/Protest'; import type { Race } from '@core/racing/domain/entities/Race'; -import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; -import type { PenaltyType } from '@core/racing/domain/entities/Penalty'; -import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; import { AlertCircle, - Video, - Clock, - Grid3x3, - TrendingDown, - XCircle, - CheckCircle, - ArrowLeft, - Flag, AlertTriangle, - ShieldAlert, - Ban, - DollarSign, - FileWarning, - User, + ArrowLeft, Calendar, + CheckCircle, + ChevronDown, + Clock, + ExternalLink, + Flag, + Gavel, + Grid3x3, MapPin, MessageCircle, - Shield, - Gavel, Send, - ChevronDown, - ExternalLink + Shield, + ShieldAlert, + TrendingDown, + User, + Video, + XCircle } from 'lucide-react'; +import Link from 'next/link'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useMemo, useState } from 'react'; // Timeline event types interface TimelineEvent { diff --git a/apps/website/app/profile/leagues/page.tsx b/apps/website/app/profile/leagues/page.tsx index bc2963b8b..d7a7ac257 100644 --- a/apps/website/app/profile/leagues/page.tsx +++ b/apps/website/app/profile/leagues/page.tsx @@ -1,12 +1,12 @@ 'use client'; -import { useEffect, useState } from 'react'; -import Link from 'next/link'; -import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import type { League } from '@core/racing/domain/entities/League'; import type { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership'; +import Link from 'next/link'; +import { useEffect, useState } from 'react'; interface LeagueWithRole { league: League; diff --git a/apps/website/app/profile/page.tsx b/apps/website/app/profile/page.tsx index 36c4cef5c..1533d1a03 100644 --- a/apps/website/app/profile/page.tsx +++ b/apps/website/app/profile/page.tsx @@ -1,57 +1,52 @@ 'use client'; -import { useState, useEffect } from 'react'; +import CreateDriverForm from '@/components/drivers/CreateDriverForm'; +import ProfileRaceHistory from '@/components/drivers/ProfileRaceHistory'; +import ProfileSettings from '@/components/drivers/ProfileSettings'; +import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import Heading from '@/components/ui/Heading'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; +import type { + ProfileOverviewAchievementViewModel, + ProfileOverviewSocialHandleViewModel, + ProfileOverviewViewModel +} from '@core/racing/application/presenters/IProfileOverviewPresenter'; +import { + Activity, + Award, + BarChart3, + Calendar, + ChevronRight, + Clock, + Crown, + Edit3, + ExternalLink, + Flag, + Globe, + History, + Medal, + MessageCircle, + Percent, + Settings, + Shield, + Star, + Target, + TrendingUp, + Trophy, + Twitch, + Twitter, + User, + UserPlus, + Users, + Youtube, + Zap, +} from 'lucide-react'; import Image from 'next/image'; import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; -import { - User, - Trophy, - Star, - Calendar, - Users, - Flag, - Award, - TrendingUp, - Settings, - UserPlus, - ExternalLink, - Target, - Zap, - Clock, - Medal, - Crown, - ChevronRight, - Edit3, - Globe, - Twitter, - Youtube, - Twitch, - MessageCircle, - BarChart3, - History, - Shield, - Percent, - Activity, -} from 'lucide-react'; -import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; -import type { - ProfileOverviewViewModel, - ProfileOverviewDriverSummaryViewModel, - ProfileOverviewStatsViewModel, - ProfileOverviewTeamMembershipViewModel, - ProfileOverviewSocialSummaryViewModel, - ProfileOverviewExtendedProfileViewModel, - ProfileOverviewAchievementViewModel, - ProfileOverviewSocialHandleViewModel, -} from '@core/racing/application/presenters/IProfileOverviewPresenter'; -import CreateDriverForm from '@/components/drivers/CreateDriverForm'; -import Card from '@/components/ui/Card'; -import Button from '@/components/ui/Button'; -import Heading from '@/components/ui/Heading'; -import ProfileRaceHistory from '@/components/drivers/ProfileRaceHistory'; -import ProfileSettings from '@/components/drivers/ProfileSettings'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffect, useState } from 'react'; // ============================================================================ // TYPES diff --git a/apps/website/app/profile/sponsorship-requests/page.tsx b/apps/website/app/profile/sponsorship-requests/page.tsx index b49c77b89..7555fbb42 100644 --- a/apps/website/app/profile/sponsorship-requests/page.tsx +++ b/apps/website/app/profile/sponsorship-requests/page.tsx @@ -1,16 +1,16 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; -import { useRouter } from 'next/navigation'; -import Card from '@/components/ui/Card'; -import Button from '@/components/ui/Button'; import Breadcrumbs from '@/components/layout/Breadcrumbs'; import PendingSponsorshipRequests, { type PendingRequestDTO } from '@/components/sponsors/PendingSponsorshipRequests'; +import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import { useRouter } from 'next/navigation'; +import { useCallback, useEffect, useState } from 'react'; -import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; -import { Handshake, User, Users, Trophy, ChevronRight, Building, AlertTriangle } from 'lucide-react'; +import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter'; +import { AlertTriangle, Building, ChevronRight, Handshake, Trophy, User, Users } from 'lucide-react'; import Link from 'next/link'; interface EntitySection { diff --git a/apps/website/app/races/[id]/page.tsx b/apps/website/app/races/[id]/page.tsx index 3bf767bee..d3ce3aac0 100644 --- a/apps/website/app/races/[id]/page.tsx +++ b/apps/website/app/races/[id]/page.tsx @@ -1,42 +1,41 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { useRouter, useParams } from 'next/navigation'; -import Link from 'next/link'; +import Breadcrumbs from '@/components/layout/Breadcrumbs'; +import EndRaceModal from '@/components/leagues/EndRaceModal'; +import FileProtestModal from '@/components/races/FileProtestModal'; +import SponsorInsightsCard, { MetricBuilders, SlotTemplates, useSponsorMode } from '@/components/sponsors/SponsorInsightsCard'; import Button from '@/components/ui/Button'; import Card from '@/components/ui/Card'; import Heading from '@/components/ui/Heading'; -import Breadcrumbs from '@/components/layout/Breadcrumbs'; -import FileProtestModal from '@/components/races/FileProtestModal'; -import EndRaceModal from '@/components/leagues/EndRaceModal'; -import SponsorInsightsCard, { useSponsorMode, MetricBuilders, SlotTemplates } from '@/components/sponsors/SponsorInsightsCard'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { apiClient } from '@/lib/apiClient'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; import { getMembership, isOwnerOrAdmin } from '@/lib/leagueMembership'; import type { - RaceDetailViewModel, RaceDetailEntryViewModel, RaceDetailUserResultViewModel, + RaceDetailViewModel, } from '@core/racing/application/presenters/IRaceDetailPresenter'; import { - Calendar, - Clock, - Car, - Trophy, - Users, - Zap, - PlayCircle, - CheckCircle2, - XCircle, - Flag, - UserPlus, - UserMinus, AlertTriangle, - ArrowRight, ArrowLeft, + ArrowRight, + Calendar, + Car, + CheckCircle2, + Clock, + Flag, + PlayCircle, Scale, + Trophy, + UserMinus, + UserPlus, + Users, + XCircle, + Zap, } from 'lucide-react'; -import { RaceDetailPresenter } from '@/lib/presenters/RaceDetailPresenter'; +import Link from 'next/link'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; export default function RaceDetailPage() { const router = useRouter(); diff --git a/apps/website/app/races/[id]/results/page.tsx b/apps/website/app/races/[id]/results/page.tsx index a237bcac5..9d8f60ef6 100644 --- a/apps/website/app/races/[id]/results/page.tsx +++ b/apps/website/app/races/[id]/results/page.tsx @@ -1,18 +1,17 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { useRouter, useParams } from 'next/navigation'; -import { ArrowLeft, Zap, Trophy, Users, Clock, Calendar } from 'lucide-react'; +import Breadcrumbs from '@/components/layout/Breadcrumbs'; +import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal'; +import ImportResultsForm from '@/components/races/ImportResultsForm'; +import ResultsTable from '@/components/races/ResultsTable'; import Button from '@/components/ui/Button'; import Card from '@/components/ui/Card'; -import Breadcrumbs from '@/components/layout/Breadcrumbs'; -import ResultsTable from '@/components/races/ResultsTable'; -import ImportResultsForm from '@/components/races/ImportResultsForm'; -import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { raceResultsService } from '@/lib/services/races/RaceResultsService'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import type { RaceResultsDetailViewModel } from '@/lib/view-models'; +import { ArrowLeft, Calendar, Trophy, Users, Zap } from 'lucide-react'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; export default function RaceResultsPage() { const router = useRouter(); diff --git a/apps/website/app/races/[id]/stewarding/page.tsx b/apps/website/app/races/[id]/stewarding/page.tsx index fed69e5f5..747a6bbe9 100644 --- a/apps/website/app/races/[id]/stewarding/page.tsx +++ b/apps/website/app/races/[id]/stewarding/page.tsx @@ -1,31 +1,25 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { useParams, useRouter } from 'next/navigation'; -import Link from 'next/link'; -import { - AlertTriangle, - Clock, - CheckCircle, - Flag, - Calendar, - MapPin, - AlertCircle, - Video, - Gavel, - ArrowLeft, - Scale, - ChevronRight, - Users, - Trophy, -} from 'lucide-react'; -import Card from '@/components/ui/Card'; -import Button from '@/components/ui/Button'; import Breadcrumbs from '@/components/layout/Breadcrumbs'; +import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import type { RacePenaltiesViewModel, RaceProtestsViewModel } from '@/lib/apiClient'; import { apiClient } from '@/lib/apiClient'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; -import type { RaceProtestsViewModel, RacePenaltiesViewModel } from '@/lib/apiClient'; +import { + AlertCircle, + AlertTriangle, + ArrowLeft, + CheckCircle, + Clock, + Flag, + Gavel, + Scale, + Video +} from 'lucide-react'; +import Link from 'next/link'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; export default function RaceStewardingPage() { const params = useParams(); diff --git a/apps/website/app/teams/[id]/page.tsx b/apps/website/app/teams/[id]/page.tsx index 979b8b125..65eac851b 100644 --- a/apps/website/app/teams/[id]/page.tsx +++ b/apps/website/app/teams/[id]/page.tsx @@ -1,24 +1,22 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; -import { useParams } from 'next/navigation'; -import Image from 'next/image'; -import Link from 'next/link'; -import Card from '@/components/ui/Card'; -import Button from '@/components/ui/Button'; import Breadcrumbs from '@/components/layout/Breadcrumbs'; -import SponsorInsightsCard, { useSponsorMode, MetricBuilders, SlotTemplates } from '@/components/sponsors/SponsorInsightsCard'; +import SponsorInsightsCard, { MetricBuilders, SlotTemplates, useSponsorMode } from '@/components/sponsors/SponsorInsightsCard'; +import Button from '@/components/ui/Button'; +import Card from '@/components/ui/Card'; +import Image from 'next/image'; +import { useParams } from 'next/navigation'; +import { useCallback, useEffect, useState } from 'react'; -import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter'; -import { TeamDetailsPresenter } from '@/lib/presenters/TeamDetailsPresenter'; -import type { TeamDetailsViewModel } from '@core/racing/application/presenters/ITeamDetailsPresenter'; +import JoinTeamButton from '@/components/teams/JoinTeamButton'; +import TeamAdmin from '@/components/teams/TeamAdmin'; import TeamRoster from '@/components/teams/TeamRoster'; import TeamStandings from '@/components/teams/TeamStandings'; -import TeamAdmin from '@/components/teams/TeamAdmin'; -import JoinTeamButton from '@/components/teams/JoinTeamButton'; +import { TeamDetailsPresenter } from '@/lib/presenters/TeamDetailsPresenter'; +import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter'; +import type { TeamDetailsViewModel } from '@core/racing/application/presenters/ITeamDetailsPresenter'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import { Users, Trophy, TrendingUp, Star, Zap } from 'lucide-react'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; type TeamRole = 'owner' | 'manager' | 'driver'; diff --git a/apps/website/components/dev/DevToolbar.tsx b/apps/website/components/dev/DevToolbar.tsx index 8a45d5521..e86bcd007 100644 --- a/apps/website/components/dev/DevToolbar.tsx +++ b/apps/website/components/dev/DevToolbar.tsx @@ -1,28 +1,27 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { useRouter } from 'next/navigation'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import type { NotificationUrgency } from '@core/notifications/application'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { - Bell, + AlertCircle, AlertTriangle, - Vote, - Shield, + Award, + Bell, + BellRing, + Building2, ChevronDown, ChevronUp, + LogIn, + LogOut, + MessageSquare, + Shield, + TrendingUp, + User, + Vote, Wrench, X, - MessageSquare, - AlertCircle, - BellRing, - User, - Building2, - LogOut, - LogIn, - TrendingUp, - Award, } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; type DemoNotificationType = 'protest_filed' | 'defense_requested' | 'vote_required' | 'race_performance_summary' | 'race_final_results'; type DemoUrgency = 'silent' | 'toast' | 'modal'; diff --git a/apps/website/components/leagues/JoinLeagueButton.tsx b/apps/website/components/leagues/JoinLeagueButton.tsx index c3808e768..f068b96cc 100644 --- a/apps/website/components/leagues/JoinLeagueButton.tsx +++ b/apps/website/components/leagues/JoinLeagueButton.tsx @@ -1,9 +1,9 @@ 'use client'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import { getMembership } from '@/lib/leagueMembership'; import { useState } from 'react'; import Button from '../ui/Button'; -import { getMembership, type MembershipStatus } from '@/lib/leagueMembership'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; interface JoinLeagueButtonProps { leagueId: string; diff --git a/apps/website/components/leagues/LeagueAdmin.tsx b/apps/website/components/leagues/LeagueAdmin.tsx index a5a6e31ea..8feeeaeed 100644 --- a/apps/website/components/leagues/LeagueAdmin.tsx +++ b/apps/website/components/leagues/LeagueAdmin.tsx @@ -1,41 +1,41 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; -import { useRouter, useSearchParams, usePathname } from 'next/navigation'; -import Button from '../ui/Button'; -import Card from '../ui/Card'; -import LeagueMembers from './LeagueMembers'; -import ScheduleRaceForm from './ScheduleRaceForm'; +import DriverIdentity from '@/components/drivers/DriverIdentity'; +import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; +import Modal from '@/components/ui/Modal'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import type { MembershipRole } from '@/lib/leagueMembership'; +import type { LeagueSummaryViewModel } from '@/lib/presenters/LeagueAdminPresenter'; import { - loadLeagueJoinRequests, approveLeagueJoinRequest, - rejectLeagueJoinRequest, - loadLeagueOwnerSummary, loadLeagueConfig, + loadLeagueJoinRequests, + loadLeagueOwnerSummary, loadLeagueProtests, + loadLeagueSeasons, + rejectLeagueJoinRequest, removeLeagueMember as removeLeagueMemberCommand, updateLeagueMemberRole as updateLeagueMemberRoleCommand, - loadLeagueSeasons, + type LeagueAdminProtestsViewModel, type LeagueJoinRequestViewModel, type LeagueOwnerSummaryViewModel, - type LeagueAdminProtestsViewModel, type LeagueSeasonSummaryViewModel, } from '@/lib/presenters/LeagueAdminPresenter'; import type { LeagueConfigFormModel } from '@core/racing/application'; -import type { LeagueSummaryViewModel } from '@/lib/presenters/LeagueAdminPresenter'; +import { AlertTriangle, Calendar, Car, CheckCircle, Clock, DollarSign, Download, Flag, Paintbrush, Trophy, Upload, User, Wallet, XCircle } from 'lucide-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useCallback, useEffect, useState } from 'react'; +import Button from '../ui/Button'; +import Card from '../ui/Card'; import { LeagueBasicsSection } from './LeagueBasicsSection'; -import { LeagueStructureSection } from './LeagueStructureSection'; -import { LeagueScoringSection } from './LeagueScoringSection'; import { LeagueDropSection } from './LeagueDropSection'; -import { LeagueTimingsSection } from './LeagueTimingsSection'; -import { LeagueSponsorshipsSection } from './LeagueSponsorshipsSection'; +import LeagueMembers from './LeagueMembers'; import { LeagueMembershipFeesSection } from './LeagueMembershipFeesSection'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import type { MembershipRole } from '@/lib/leagueMembership'; -import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; -import DriverIdentity from '@/components/drivers/DriverIdentity'; -import Modal from '@/components/ui/Modal'; -import { AlertTriangle, CheckCircle, Clock, XCircle, Flag, Calendar, User, DollarSign, Wallet, Paintbrush, Trophy, Download, Car, Upload } from 'lucide-react'; +import { LeagueScoringSection } from './LeagueScoringSection'; +import { LeagueSponsorshipsSection } from './LeagueSponsorshipsSection'; +import { LeagueStructureSection } from './LeagueStructureSection'; +import { LeagueTimingsSection } from './LeagueTimingsSection'; +import ScheduleRaceForm from './ScheduleRaceForm'; type JoinRequest = LeagueJoinRequestViewModel; diff --git a/apps/website/components/leagues/LeagueMembers.tsx b/apps/website/components/leagues/LeagueMembers.tsx index 5486e2001..dff80acb7 100644 --- a/apps/website/components/leagues/LeagueMembers.tsx +++ b/apps/website/components/leagues/LeagueMembers.tsx @@ -1,15 +1,15 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; import DriverIdentity from '@/components/drivers/DriverIdentity'; -import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; -import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { getLeagueMembers, type LeagueMembership, type MembershipRole, } from '@/lib/leagueMembership'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; +import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; +import { useCallback, useEffect, useState } from 'react'; interface LeagueMembersProps { leagueId: string; diff --git a/apps/website/components/leagues/LeagueSchedule.tsx b/apps/website/components/leagues/LeagueSchedule.tsx index 26e207750..d58a51412 100644 --- a/apps/website/components/leagues/LeagueSchedule.tsx +++ b/apps/website/components/leagues/LeagueSchedule.tsx @@ -1,10 +1,9 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; -import { useRouter } from 'next/navigation'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; -import { createLeagueSchedulePresenter } from '@/lib/presenters/factories'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import type { LeagueScheduleRaceItemViewModel } from '@/lib/presenters/LeagueSchedulePresenter'; +import { useRouter } from 'next/navigation'; +import { useCallback, useEffect, useState } from 'react'; interface LeagueScheduleProps { leagueId: string; diff --git a/apps/website/components/leagues/LeagueSponsorshipsSection.tsx b/apps/website/components/leagues/LeagueSponsorshipsSection.tsx index 11ab77bfe..9a7cee861 100644 --- a/apps/website/components/leagues/LeagueSponsorshipsSection.tsx +++ b/apps/website/components/leagues/LeagueSponsorshipsSection.tsx @@ -1,13 +1,13 @@ 'use client'; -import { useState, useEffect, useCallback } from 'react'; +import { Award, DollarSign, Star, X } from 'lucide-react'; +import { useCallback, useEffect, useState } from 'react'; +import PendingSponsorshipRequests, { type PendingRequestDTO } from '../sponsors/PendingSponsorshipRequests'; import Button from '../ui/Button'; import Input from '../ui/Input'; -import { DollarSign, Star, Award, Plus, X, Bell } from 'lucide-react'; -import PendingSponsorshipRequests, { type PendingRequestDTO } from '../sponsors/PendingSponsorshipRequests'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; interface SponsorshipSlot { tier: 'main' | 'secondary'; diff --git a/apps/website/components/leagues/MembershipStatus.tsx b/apps/website/components/leagues/MembershipStatus.tsx index cc808fabe..f180da1fd 100644 --- a/apps/website/components/leagues/MembershipStatus.tsx +++ b/apps/website/components/leagues/MembershipStatus.tsx @@ -1,7 +1,7 @@ 'use client'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { getMembership, type MembershipRole } from '@/lib/leagueMembership'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; interface MembershipStatusProps { leagueId: string; diff --git a/apps/website/components/notifications/NotificationCenter.tsx b/apps/website/components/notifications/NotificationCenter.tsx index 4aa4f1a33..cf2fdb299 100644 --- a/apps/website/components/notifications/NotificationCenter.tsx +++ b/apps/website/components/notifications/NotificationCenter.tsx @@ -1,23 +1,20 @@ 'use client'; -import React, { useState, useEffect, useRef } from 'react'; -import { useRouter } from 'next/navigation'; -import Link from 'next/link'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import type { Notification } from '@core/notifications/application'; import { - Bell, AlertTriangle, - Shield, - Vote, - Trophy, - Users, - Flag, - X, - Check, + Bell, CheckCheck, ExternalLink, + Flag, + Shield, + Trophy, + Users, + Vote } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useEffect, useRef, useState } from 'react'; const notificationIcons: Record = { protest_filed: AlertTriangle, diff --git a/apps/website/components/notifications/NotificationProvider.tsx b/apps/website/components/notifications/NotificationProvider.tsx index 4b8189757..a51ea0d7e 100644 --- a/apps/website/components/notifications/NotificationProvider.tsx +++ b/apps/website/components/notifications/NotificationProvider.tsx @@ -1,11 +1,11 @@ 'use client'; -import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react'; import type { Notification } from '@core/notifications/application'; -import ToastNotification from './ToastNotification'; import ModalNotification from './ModalNotification'; +import ToastNotification from './ToastNotification'; interface NotificationContextValue { notifications: Notification[]; diff --git a/apps/website/components/profile/UserPill.tsx b/apps/website/components/profile/UserPill.tsx index 5a8a1f6d9..7ffe49772 100644 --- a/apps/website/components/profile/UserPill.tsx +++ b/apps/website/components/profile/UserPill.tsx @@ -1,15 +1,15 @@ 'use client'; +import { useAuth } from '@/lib/auth/AuthContext'; +import { AnimatePresence, motion, useReducedMotion } from 'framer-motion'; +import { BarChart3, Building2, ChevronDown, CreditCard, Handshake, LogOut, Megaphone, Paintbrush, Settings, TrendingUp, Trophy } from 'lucide-react'; import Link from 'next/link'; import { useEffect, useMemo, useState } from 'react'; -import { motion, AnimatePresence, useReducedMotion } from 'framer-motion'; -import { LogOut, Settings, Star, Paintbrush, Building2, BarChart3, Megaphone, CreditCard, Handshake, ChevronDown, TrendingUp, Trophy } from 'lucide-react'; -import { useAuth } from '@/lib/auth/AuthContext'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; -import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; // Hook to detect sponsor mode function useSponsorMode(): boolean { diff --git a/apps/website/components/teams/CreateTeamForm.tsx b/apps/website/components/teams/CreateTeamForm.tsx index 931849522..79de2270e 100644 --- a/apps/website/components/teams/CreateTeamForm.tsx +++ b/apps/website/components/teams/CreateTeamForm.tsx @@ -1,10 +1,10 @@ 'use client'; -import { useState } from 'react'; -import { useRouter } from 'next/navigation'; import Button from '@/components/ui/Button'; import Input from '@/components/ui/Input'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; interface CreateTeamFormProps { onCancel?: () => void; diff --git a/apps/website/components/teams/JoinTeamButton.tsx b/apps/website/components/teams/JoinTeamButton.tsx index d692de05d..c18ccb28b 100644 --- a/apps/website/components/teams/JoinTeamButton.tsx +++ b/apps/website/components/teams/JoinTeamButton.tsx @@ -1,8 +1,8 @@ 'use client'; -import { useState, useEffect } from 'react'; import Button from '@/components/ui/Button'; -import { useEffectiveDriverId } from '@/lib/currentDriver'; +import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; +import { useEffect, useState } from 'react'; type TeamMembershipStatus = 'active' | 'pending' | 'inactive'; diff --git a/apps/website/lib/currentDriver.ts b/apps/website/hooks/useEffectiveDriverId.ts similarity index 100% rename from apps/website/lib/currentDriver.ts rename to apps/website/hooks/useEffectiveDriverId.ts diff --git a/apps/website/lib/apiClient.ts b/apps/website/lib/apiClient.ts deleted file mode 100644 index 8b5862558..000000000 --- a/apps/website/lib/apiClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @deprecated This legacy API client has been refactored into domain-specific clients. - * Please use the new API client from './api' instead. - * - * TODO: Remove this file once all consumers have migrated to the new API client structure. - */ - -// Re-export the new API client for backward compatibility -export { api as apiClient } from './api'; - -// Re-export DTO types for backward compatibility -export type * from './dtos';