This commit is contained in:
2025-12-18 14:30:19 +01:00
parent bf1f09c774
commit b476bb7e99
29 changed files with 273 additions and 307 deletions

View File

@@ -1,12 +1,12 @@
'use client'; 'use client';
import React, { useState, useEffect } from 'react';
import { useParams, usePathname, useRouter } from 'next/navigation';
import Breadcrumbs from '@/components/layout/Breadcrumbs'; import Breadcrumbs from '@/components/layout/Breadcrumbs';
import LeagueHeader from '@/components/leagues/LeagueHeader'; import LeagueHeader from '@/components/leagues/LeagueHeader';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import type { League } from '@core/racing/domain/entities/League'; 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 // Main sponsor info for "by XYZ" display
interface MainSponsorInfo { interface MainSponsorInfo {

View File

@@ -1,33 +1,32 @@
'use client'; 'use client';
import { useState, useEffect, useMemo } from 'react'; import DriverIdentity from '@/components/drivers/DriverIdentity';
import { useRouter, useParams } from 'next/navigation'; import EndRaceModal from '@/components/leagues/EndRaceModal';
import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card';
import JoinLeagueButton from '@/components/leagues/JoinLeagueButton'; import JoinLeagueButton from '@/components/leagues/JoinLeagueButton';
import LeagueActivityFeed from '@/components/leagues/LeagueActivityFeed'; 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, { import SponsorInsightsCard, {
useSponsorMode,
MetricBuilders, MetricBuilders,
SlotTemplates, SlotTemplates,
useSponsorMode,
type SponsorMetric, type SponsorMetric,
} from '@/components/sponsors/SponsorInsightsCard'; } 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 { import {
League,
Driver, Driver,
EntityMappers, EntityMappers,
League,
Race,
type DriverDTO, type DriverDTO,
type LeagueScoringConfigDTO, type LeagueScoringConfigDTO,
Race,
} from '@core/racing'; } from '@core/racing';
import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter'; import { Calendar, ExternalLink, Star, Trophy, Users } from 'lucide-react';
import { Trophy, Star, ExternalLink, Calendar, Users } from 'lucide-react'; import { useParams, useRouter } from 'next/navigation';
import { getMembership, getLeagueMembers } from '@/lib/leagueMembership'; import { useEffect, useMemo, useState } from 'react';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import { getLeagueRoleDisplay } from '@/lib/leagueRoles';
// Sponsor info type // Sponsor info type
interface SponsorInfo { interface SponsorInfo {

View File

@@ -1,13 +1,11 @@
'use client'; 'use client';
import { useParams } from 'next/navigation';
import Card from '@/components/ui/Card';
import LeagueSchedule from '@/components/leagues/LeagueSchedule'; import LeagueSchedule from '@/components/leagues/LeagueSchedule';
import ScheduleRaceForm from '@/components/leagues/ScheduleRaceForm'; import Card from '@/components/ui/Card';
import { useState, useEffect } from 'react'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useRouter } from 'next/navigation';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import { useParams, useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
export default function LeagueSchedulePage() { export default function LeagueSchedulePage() {
const params = useParams(); const params = useParams();

View File

@@ -1,23 +1,21 @@
'use client'; 'use client';
import { useState, useEffect, useMemo } from 'react'; import { ReadonlyLeagueInfo } from '@/components/leagues/ReadonlyLeagueInfo';
import { useParams, useRouter } from 'next/navigation'; import DriverSummaryPill from '@/components/profile/DriverSummaryPill';
import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; 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 { LeagueFullConfigPresenter } from '@/lib/presenters/LeagueFullConfigPresenter';
import { LeagueScoringPresetsPresenter } from '@/lib/presenters/LeagueScoringPresetsPresenter'; 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 { 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 { 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 { EntityMappers } from '@core/racing/application/mappers/EntityMappers';
import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; import type { LeagueScoringPresetDTO } from '@core/racing/application/ports/LeagueScoringPresetProvider';
import { AlertTriangle, Settings, Trophy, Calendar, TrendingDown, Edit, Users, UserCog } from 'lucide-react'; 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() { export default function LeagueSettingsPage() {
const params = useParams(); const params = useParams();

View File

@@ -1,14 +1,13 @@
'use client'; '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 { 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 { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import { AlertTriangle, Building, DollarSign } from 'lucide-react';
import type { League } from '@core/racing/domain/entities/League'; 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() { export default function LeagueSponsorshipsPage() {
const params = useParams(); const params = useParams();

View File

@@ -1,16 +1,15 @@
'use client'; '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 StandingsTable from '@/components/leagues/StandingsTable';
import { getLeagueStandings } from '@/lib/services/leagues/LeagueService'; import Card from '@/components/ui/Card';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import type { DriverDto, LeagueMembership } from '@/lib/dtos';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import { getLeagueStandings } from '@/lib/services/leagues/LeagueService';
import type { LeagueStandingsViewModel } from '@/lib/view-models'; import type { LeagueStandingsViewModel } from '@/lib/view-models';
import type { StandingEntryViewModel } from '@/lib/view-models/StandingEntryViewModel'; import type { StandingEntryViewModel } from '@/lib/view-models/StandingEntryViewModel';
import type { DriverDto } from '@/lib/dtos'; import { useParams } from 'next/navigation';
import type { LeagueMembership } from '@/lib/dtos'; import { useCallback, useEffect, useState } from 'react';
export default function LeagueStandingsPage() { export default function LeagueStandingsPage() {
const params = useParams(); const params = useParams();

View File

@@ -1,24 +1,32 @@
'use client'; '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 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 { 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 type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; 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 { import {
AlertTriangle, Clock, CheckCircle, Flag, ChevronRight, AlertCircle,
Calendar, MapPin, AlertCircle, Video, Gavel AlertTriangle,
Calendar,
CheckCircle,
ChevronRight,
Clock,
Flag,
Gavel,
MapPin,
Video
} from 'lucide-react'; } from 'lucide-react';
import Link from 'next/link';
import { useParams } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';
interface RaceWithProtests { interface RaceWithProtests {
race: Race; race: Race;

View File

@@ -1,42 +1,39 @@
'use client'; '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 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 { 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 { Protest } from '@core/racing/domain/entities/Protest';
import type { Race } from '@core/racing/domain/entities/Race'; 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 { import {
AlertCircle, AlertCircle,
Video,
Clock,
Grid3x3,
TrendingDown,
XCircle,
CheckCircle,
ArrowLeft,
Flag,
AlertTriangle, AlertTriangle,
ShieldAlert, ArrowLeft,
Ban,
DollarSign,
FileWarning,
User,
Calendar, Calendar,
CheckCircle,
ChevronDown,
Clock,
ExternalLink,
Flag,
Gavel,
Grid3x3,
MapPin, MapPin,
MessageCircle, MessageCircle,
Shield,
Gavel,
Send, Send,
ChevronDown, Shield,
ExternalLink ShieldAlert,
TrendingDown,
User,
Video,
XCircle
} from 'lucide-react'; } from 'lucide-react';
import Link from 'next/link';
import { useParams, useRouter } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';
// Timeline event types // Timeline event types
interface TimelineEvent { interface TimelineEvent {

View File

@@ -1,12 +1,12 @@
'use client'; '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 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 { League } from '@core/racing/domain/entities/League';
import type { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership'; import type { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
import Link from 'next/link';
import { useEffect, useState } from 'react';
interface LeagueWithRole { interface LeagueWithRole {
league: League; league: League;

View File

@@ -1,57 +1,52 @@
'use client'; '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 Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter, useSearchParams } from 'next/navigation'; import { useRouter, useSearchParams } from 'next/navigation';
import { import { useEffect, useState } from 'react';
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';
// ============================================================================ // ============================================================================
// TYPES // TYPES

View File

@@ -1,16 +1,16 @@
'use client'; '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 Breadcrumbs from '@/components/layout/Breadcrumbs';
import PendingSponsorshipRequests, { type PendingRequestDTO } from '@/components/sponsors/PendingSponsorshipRequests'; 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 '@/hooks/useEffectiveDriverId';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; 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'; import Link from 'next/link';
interface EntitySection { interface EntitySection {

View File

@@ -1,42 +1,41 @@
'use client'; 'use client';
import { useState, useEffect } from 'react'; import Breadcrumbs from '@/components/layout/Breadcrumbs';
import { useRouter, useParams } from 'next/navigation'; import EndRaceModal from '@/components/leagues/EndRaceModal';
import Link from 'next/link'; import FileProtestModal from '@/components/races/FileProtestModal';
import SponsorInsightsCard, { MetricBuilders, SlotTemplates, useSponsorMode } from '@/components/sponsors/SponsorInsightsCard';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import Breadcrumbs from '@/components/layout/Breadcrumbs'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import FileProtestModal from '@/components/races/FileProtestModal';
import EndRaceModal from '@/components/leagues/EndRaceModal';
import SponsorInsightsCard, { useSponsorMode, MetricBuilders, SlotTemplates } from '@/components/sponsors/SponsorInsightsCard';
import { apiClient } from '@/lib/apiClient'; import { apiClient } from '@/lib/apiClient';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import { getMembership, isOwnerOrAdmin } from '@/lib/leagueMembership'; import { getMembership, isOwnerOrAdmin } from '@/lib/leagueMembership';
import type { import type {
RaceDetailViewModel,
RaceDetailEntryViewModel, RaceDetailEntryViewModel,
RaceDetailUserResultViewModel, RaceDetailUserResultViewModel,
RaceDetailViewModel,
} from '@core/racing/application/presenters/IRaceDetailPresenter'; } from '@core/racing/application/presenters/IRaceDetailPresenter';
import { import {
Calendar,
Clock,
Car,
Trophy,
Users,
Zap,
PlayCircle,
CheckCircle2,
XCircle,
Flag,
UserPlus,
UserMinus,
AlertTriangle, AlertTriangle,
ArrowRight,
ArrowLeft, ArrowLeft,
ArrowRight,
Calendar,
Car,
CheckCircle2,
Clock,
Flag,
PlayCircle,
Scale, Scale,
Trophy,
UserMinus,
UserPlus,
Users,
XCircle,
Zap,
} from 'lucide-react'; } 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() { export default function RaceDetailPage() {
const router = useRouter(); const router = useRouter();

View File

@@ -1,18 +1,17 @@
'use client'; 'use client';
import { useState, useEffect } from 'react'; import Breadcrumbs from '@/components/layout/Breadcrumbs';
import { useRouter, useParams } from 'next/navigation'; import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal';
import { ArrowLeft, Zap, Trophy, Users, Clock, Calendar } from 'lucide-react'; import ImportResultsForm from '@/components/races/ImportResultsForm';
import ResultsTable from '@/components/races/ResultsTable';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Breadcrumbs from '@/components/layout/Breadcrumbs'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import ResultsTable from '@/components/races/ResultsTable';
import ImportResultsForm from '@/components/races/ImportResultsForm';
import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal';
import { raceResultsService } from '@/lib/services/races/RaceResultsService'; 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 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() { export default function RaceResultsPage() {
const router = useRouter(); const router = useRouter();

View File

@@ -1,31 +1,25 @@
'use client'; '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 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 { apiClient } from '@/lib/apiClient';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import {
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; AlertCircle,
import type { RaceProtestsViewModel, RacePenaltiesViewModel } from '@/lib/apiClient'; 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() { export default function RaceStewardingPage() {
const params = useParams(); const params = useParams();

View File

@@ -1,24 +1,22 @@
'use client'; '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 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 JoinTeamButton from '@/components/teams/JoinTeamButton';
import { TeamDetailsPresenter } from '@/lib/presenters/TeamDetailsPresenter'; import TeamAdmin from '@/components/teams/TeamAdmin';
import type { TeamDetailsViewModel } from '@core/racing/application/presenters/ITeamDetailsPresenter';
import TeamRoster from '@/components/teams/TeamRoster'; import TeamRoster from '@/components/teams/TeamRoster';
import TeamStandings from '@/components/teams/TeamStandings'; import TeamStandings from '@/components/teams/TeamStandings';
import TeamAdmin from '@/components/teams/TeamAdmin'; import { TeamDetailsPresenter } from '@/lib/presenters/TeamDetailsPresenter';
import JoinTeamButton from '@/components/teams/JoinTeamButton'; import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter';
import type { TeamDetailsViewModel } from '@core/racing/application/presenters/ITeamDetailsPresenter';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { Users, Trophy, TrendingUp, Star, Zap } from 'lucide-react';
type TeamRole = 'owner' | 'manager' | 'driver'; type TeamRole = 'owner' | 'manager' | 'driver';

View File

@@ -1,28 +1,27 @@
'use client'; 'use client';
import { useState, useEffect } from 'react'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useRouter } from 'next/navigation';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import type { NotificationUrgency } from '@core/notifications/application';
import { import {
Bell, AlertCircle,
AlertTriangle, AlertTriangle,
Vote, Award,
Shield, Bell,
BellRing,
Building2,
ChevronDown, ChevronDown,
ChevronUp, ChevronUp,
LogIn,
LogOut,
MessageSquare,
Shield,
TrendingUp,
User,
Vote,
Wrench, Wrench,
X, X,
MessageSquare,
AlertCircle,
BellRing,
User,
Building2,
LogOut,
LogIn,
TrendingUp,
Award,
} from 'lucide-react'; } 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 DemoNotificationType = 'protest_filed' | 'defense_requested' | 'vote_required' | 'race_performance_summary' | 'race_final_results';
type DemoUrgency = 'silent' | 'toast' | 'modal'; type DemoUrgency = 'silent' | 'toast' | 'modal';

View File

@@ -1,9 +1,9 @@
'use client'; 'use client';
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { getMembership } from '@/lib/leagueMembership';
import { useState } from 'react'; import { useState } from 'react';
import Button from '../ui/Button'; import Button from '../ui/Button';
import { getMembership, type MembershipStatus } from '@/lib/leagueMembership';
import { useEffectiveDriverId } from '@/lib/currentDriver';
interface JoinLeagueButtonProps { interface JoinLeagueButtonProps {
leagueId: string; leagueId: string;

View File

@@ -1,41 +1,41 @@
'use client'; 'use client';
import { useState, useEffect, useCallback } from 'react'; import DriverIdentity from '@/components/drivers/DriverIdentity';
import { useRouter, useSearchParams, usePathname } from 'next/navigation'; import DriverSummaryPill from '@/components/profile/DriverSummaryPill';
import Button from '../ui/Button'; import Modal from '@/components/ui/Modal';
import Card from '../ui/Card'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import LeagueMembers from './LeagueMembers'; import type { MembershipRole } from '@/lib/leagueMembership';
import ScheduleRaceForm from './ScheduleRaceForm'; import type { LeagueSummaryViewModel } from '@/lib/presenters/LeagueAdminPresenter';
import { import {
loadLeagueJoinRequests,
approveLeagueJoinRequest, approveLeagueJoinRequest,
rejectLeagueJoinRequest,
loadLeagueOwnerSummary,
loadLeagueConfig, loadLeagueConfig,
loadLeagueJoinRequests,
loadLeagueOwnerSummary,
loadLeagueProtests, loadLeagueProtests,
loadLeagueSeasons,
rejectLeagueJoinRequest,
removeLeagueMember as removeLeagueMemberCommand, removeLeagueMember as removeLeagueMemberCommand,
updateLeagueMemberRole as updateLeagueMemberRoleCommand, updateLeagueMemberRole as updateLeagueMemberRoleCommand,
loadLeagueSeasons, type LeagueAdminProtestsViewModel,
type LeagueJoinRequestViewModel, type LeagueJoinRequestViewModel,
type LeagueOwnerSummaryViewModel, type LeagueOwnerSummaryViewModel,
type LeagueAdminProtestsViewModel,
type LeagueSeasonSummaryViewModel, type LeagueSeasonSummaryViewModel,
} from '@/lib/presenters/LeagueAdminPresenter'; } from '@/lib/presenters/LeagueAdminPresenter';
import type { LeagueConfigFormModel } from '@core/racing/application'; 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 { LeagueBasicsSection } from './LeagueBasicsSection';
import { LeagueStructureSection } from './LeagueStructureSection';
import { LeagueScoringSection } from './LeagueScoringSection';
import { LeagueDropSection } from './LeagueDropSection'; import { LeagueDropSection } from './LeagueDropSection';
import { LeagueTimingsSection } from './LeagueTimingsSection'; import LeagueMembers from './LeagueMembers';
import { LeagueSponsorshipsSection } from './LeagueSponsorshipsSection';
import { LeagueMembershipFeesSection } from './LeagueMembershipFeesSection'; import { LeagueMembershipFeesSection } from './LeagueMembershipFeesSection';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { LeagueScoringSection } from './LeagueScoringSection';
import type { MembershipRole } from '@/lib/leagueMembership'; import { LeagueSponsorshipsSection } from './LeagueSponsorshipsSection';
import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; import { LeagueStructureSection } from './LeagueStructureSection';
import DriverIdentity from '@/components/drivers/DriverIdentity'; import { LeagueTimingsSection } from './LeagueTimingsSection';
import Modal from '@/components/ui/Modal'; import ScheduleRaceForm from './ScheduleRaceForm';
import { AlertTriangle, CheckCircle, Clock, XCircle, Flag, Calendar, User, DollarSign, Wallet, Paintbrush, Trophy, Download, Car, Upload } from 'lucide-react';
type JoinRequest = LeagueJoinRequestViewModel; type JoinRequest = LeagueJoinRequestViewModel;

View File

@@ -1,15 +1,15 @@
'use client'; 'use client';
import { useState, useEffect, useCallback } from 'react';
import DriverIdentity from '@/components/drivers/DriverIdentity'; import DriverIdentity from '@/components/drivers/DriverIdentity';
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { EntityMappers } from '@core/racing/application/mappers/EntityMappers';
import { import {
getLeagueMembers, getLeagueMembers,
type LeagueMembership, type LeagueMembership,
type MembershipRole, type MembershipRole,
} from '@/lib/leagueMembership'; } 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 { interface LeagueMembersProps {
leagueId: string; leagueId: string;

View File

@@ -1,10 +1,9 @@
'use client'; 'use client';
import { useState, useEffect, useCallback } from 'react'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useRouter } from 'next/navigation';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import { createLeagueSchedulePresenter } from '@/lib/presenters/factories';
import type { LeagueScheduleRaceItemViewModel } from '@/lib/presenters/LeagueSchedulePresenter'; import type { LeagueScheduleRaceItemViewModel } from '@/lib/presenters/LeagueSchedulePresenter';
import { useRouter } from 'next/navigation';
import { useCallback, useEffect, useState } from 'react';
interface LeagueScheduleProps { interface LeagueScheduleProps {
leagueId: string; leagueId: string;

View File

@@ -1,13 +1,13 @@
'use client'; '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 Button from '../ui/Button';
import Input from '../ui/Input'; 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 { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter';
import { useEffectiveDriverId } from '@/lib/currentDriver';
interface SponsorshipSlot { interface SponsorshipSlot {
tier: 'main' | 'secondary'; tier: 'main' | 'secondary';

View File

@@ -1,7 +1,7 @@
'use client'; 'use client';
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { getMembership, type MembershipRole } from '@/lib/leagueMembership'; import { getMembership, type MembershipRole } from '@/lib/leagueMembership';
import { useEffectiveDriverId } from '@/lib/currentDriver';
interface MembershipStatusProps { interface MembershipStatusProps {
leagueId: string; leagueId: string;

View File

@@ -1,23 +1,20 @@
'use client'; 'use client';
import React, { useState, useEffect, useRef } from 'react'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { useEffectiveDriverId } from '@/lib/currentDriver';
import type { Notification } from '@core/notifications/application'; import type { Notification } from '@core/notifications/application';
import { import {
Bell,
AlertTriangle, AlertTriangle,
Shield, Bell,
Vote,
Trophy,
Users,
Flag,
X,
Check,
CheckCheck, CheckCheck,
ExternalLink, ExternalLink,
Flag,
Shield,
Trophy,
Users,
Vote
} from 'lucide-react'; } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';
const notificationIcons: Record<string, typeof Bell> = { const notificationIcons: Record<string, typeof Bell> = {
protest_filed: AlertTriangle, protest_filed: AlertTriangle,

View File

@@ -1,11 +1,11 @@
'use client'; 'use client';
import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
import type { Notification } from '@core/notifications/application'; import type { Notification } from '@core/notifications/application';
import ToastNotification from './ToastNotification';
import ModalNotification from './ModalNotification'; import ModalNotification from './ModalNotification';
import ToastNotification from './ToastNotification';
interface NotificationContextValue { interface NotificationContextValue {
notifications: Notification[]; notifications: Notification[];

View File

@@ -1,15 +1,15 @@
'use client'; '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 Link from 'next/link';
import { useEffect, useMemo, useState } from 'react'; 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 type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import { EntityMappers } from '@core/racing/application/mappers/EntityMappers'; import { EntityMappers } from '@core/racing/application/mappers/EntityMappers';
import DriverSummaryPill from '@/components/profile/DriverSummaryPill';
// Hook to detect sponsor mode // Hook to detect sponsor mode
function useSponsorMode(): boolean { function useSponsorMode(): boolean {

View File

@@ -1,10 +1,10 @@
'use client'; 'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input'; 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 { interface CreateTeamFormProps {
onCancel?: () => void; onCancel?: () => void;

View File

@@ -1,8 +1,8 @@
'use client'; 'use client';
import { useState, useEffect } from 'react';
import Button from '@/components/ui/Button'; 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'; type TeamMembershipStatus = 'active' | 'pending' | 'inactive';

View File

@@ -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';