make website run

This commit is contained in:
2025-12-17 14:40:46 +01:00
parent daa4bb6576
commit a213a5cf9f
54 changed files with 196 additions and 352 deletions

View File

@@ -1,7 +1,6 @@
import { cookies } from 'next/headers'; import { cookies } from 'next/headers';
import { NextResponse } from 'next/server'; import { NextResponse } from 'next/server';
import { getAuthService } from '../../../../lib/auth';
const STATE_COOKIE = 'gp_demo_auth_state'; const STATE_COOKIE = 'gp_demo_auth_state';

View File

@@ -25,7 +25,6 @@ import {
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import { getAuthService } from '@/lib/auth';
import type { import type {
DashboardOverviewViewModel, DashboardOverviewViewModel,
DashboardFeedItemSummaryViewModel, DashboardFeedItemSummaryViewModel,

View File

@@ -36,13 +36,6 @@ import {
Megaphone, Megaphone,
DollarSign, DollarSign,
} from 'lucide-react'; } from 'lucide-react';
import {
getGetProfileOverviewUseCase,
getGetDriverTeamUseCase,
getImageService,
getGetAllTeamsUseCase,
getGetTeamMembersUseCase,
} from '@/lib/di-container';
import { AllTeamsPresenter } from '@/lib/presenters/AllTeamsPresenter'; import { AllTeamsPresenter } from '@/lib/presenters/AllTeamsPresenter';
import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter'; import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter';
import { Driver, EntityMappers, type Team } from '@core/racing'; import { Driver, EntityMappers, type Team } from '@core/racing';

View File

@@ -27,7 +27,6 @@ import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input'; import Input from '@/components/ui/Input';
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 { getGetDriversLeaderboardUseCase } from '@/lib/di-container';
import { DriversLeaderboardPresenter } from '@/lib/presenters/DriversLeaderboardPresenter'; import { DriversLeaderboardPresenter } from '@/lib/presenters/DriversLeaderboardPresenter';
import type { DriverLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/IDriversLeaderboardPresenter'; import type { DriverLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/IDriversLeaderboardPresenter';
import Image from 'next/image'; import Image from 'next/image';

View File

@@ -4,14 +4,12 @@ import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import './globals.css'; import './globals.css';
import { getAppMode } from '@/lib/mode'; import { getAppMode } from '@/lib/mode';
import { getAuthService } from '@/lib/auth';
import { AlphaNav } from '@/components/alpha/AlphaNav'; import { AlphaNav } from '@/components/alpha/AlphaNav';
import AlphaBanner from '@/components/alpha/AlphaBanner'; import AlphaBanner from '@/components/alpha/AlphaBanner';
import AlphaFooter from '@/components/alpha/AlphaFooter'; import AlphaFooter from '@/components/alpha/AlphaFooter';
import { AuthProvider } from '@/lib/auth/AuthContext'; import { AuthProvider } from '@/lib/auth/AuthContext';
import NotificationProvider from '@/components/notifications/NotificationProvider'; import NotificationProvider from '@/components/notifications/NotificationProvider';
import DevToolbar from '@/components/dev/DevToolbar'; import DevToolbar from '@/components/dev/DevToolbar';
import { initializeDIContainer } from '@/lib/di-setup';
export const dynamic = 'force-dynamic'; export const dynamic = 'force-dynamic';
@@ -50,12 +48,11 @@ export default async function RootLayout({
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {
await initializeDIContainer();
const mode = getAppMode(); const mode = getAppMode();
if (mode === 'alpha') { if (mode === 'alpha') {
const authService = getAuthService(); //const session = await authService.getCurrentSession();
const session = await authService.getCurrentSession(); const session = null;
return ( return (
<html lang="en" className="scroll-smooth overflow-x-hidden"> <html lang="en" className="scroll-smooth overflow-x-hidden">

View File

@@ -19,7 +19,6 @@ import {
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 Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import { getGetDriversLeaderboardUseCase } from '@/lib/di-container';
import { DriversLeaderboardPresenter } from '@/lib/presenters/DriversLeaderboardPresenter'; import { DriversLeaderboardPresenter } from '@/lib/presenters/DriversLeaderboardPresenter';
import type { DriverLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/IDriversLeaderboardPresenter'; import type { DriverLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/IDriversLeaderboardPresenter';
import Image from 'next/image'; import Image from 'next/image';

View File

@@ -20,7 +20,6 @@ import {
} from 'lucide-react'; } from 'lucide-react';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import { getGetDriversLeaderboardUseCase, getGetTeamsLeaderboardUseCase } from '@/lib/di-container';
import { DriversLeaderboardPresenter } from '@/lib/presenters/DriversLeaderboardPresenter'; import { DriversLeaderboardPresenter } from '@/lib/presenters/DriversLeaderboardPresenter';
import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter'; import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter';
import type { DriverLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/IDriversLeaderboardPresenter'; import type { DriverLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/IDriversLeaderboardPresenter';

View File

@@ -4,14 +4,6 @@ import React, { useState, useEffect } from 'react';
import { useParams, usePathname, useRouter } from 'next/navigation'; 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 {
getLeagueRepository,
getDriverRepository,
getLeagueMembershipRepository,
getSeasonRepository,
getSponsorRepository,
getSeasonSponsorshipRepository,
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
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';

View File

@@ -23,19 +23,6 @@ import {
type LeagueScoringConfigDTO, type LeagueScoringConfigDTO,
Race, Race,
} from '@core/racing'; } from '@core/racing';
import {
getLeagueRepository,
getRaceRepository,
getDriverRepository,
getGetLeagueScoringConfigUseCase,
getDriverStats,
getAllDriverRankings,
getGetLeagueStatsUseCase,
getSeasonRepository,
getSponsorRepository,
getSeasonSponsorshipRepository,
getCompleteRaceUseCase,
} from '@/lib/di-container';
import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter'; import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter';
import { Trophy, Star, ExternalLink, Calendar, Users } from 'lucide-react'; import { Trophy, Star, ExternalLink, Calendar, Users } from 'lucide-react';
import { getMembership, getLeagueMembers } from '@/lib/leagueMembership'; import { getMembership, getLeagueMembers } from '@/lib/leagueMembership';

View File

@@ -3,10 +3,6 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import {
getLeagueRepository,
getGetLeagueScoringConfigUseCase
} from '@/lib/di-container';
import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter'; import { LeagueScoringConfigPresenter } from '@/lib/presenters/LeagueScoringConfigPresenter';
import type { LeagueScoringConfigDTO } from '@core/racing/application/dto/LeagueScoringConfigDTO'; import type { LeagueScoringConfigDTO } from '@core/racing/application/dto/LeagueScoringConfigDTO';
import type { League } from '@core/racing/domain/entities/League'; import type { League } from '@core/racing/domain/entities/League';

View File

@@ -6,7 +6,6 @@ import LeagueSchedule from '@/components/leagues/LeagueSchedule';
import ScheduleRaceForm from '@/components/leagues/ScheduleRaceForm'; import ScheduleRaceForm from '@/components/leagues/ScheduleRaceForm';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { getLeagueMembershipRepository } from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';

View File

@@ -4,16 +4,6 @@ import { useState, useEffect, useMemo } from 'react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import {
getLeagueRepository,
getDriverRepository,
getGetLeagueFullConfigUseCase,
getLeagueMembershipRepository,
getDriverStats,
getAllDriverRankings,
getListLeagueScoringPresetsUseCase,
getTransferLeagueOwnershipUseCase
} from '@/lib/di-container';
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 { useEffectiveDriverId } from '@/lib/currentDriver';

View File

@@ -5,10 +5,6 @@ import { useParams } from 'next/navigation';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import { LeagueSponsorshipsSection } from '@/components/leagues/LeagueSponsorshipsSection'; import { LeagueSponsorshipsSection } from '@/components/leagues/LeagueSponsorshipsSection';
import {
getLeagueRepository,
getLeagueMembershipRepository,
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import { AlertTriangle, Building, DollarSign } from 'lucide-react'; import { AlertTriangle, Building, DollarSign } from 'lucide-react';

View File

@@ -9,11 +9,6 @@ import {
type DriverDTO, type DriverDTO,
type LeagueDriverSeasonStatsDTO, type LeagueDriverSeasonStatsDTO,
} from '@core/racing'; } from '@core/racing';
import {
getGetLeagueDriverSeasonStatsUseCase,
getDriverRepository,
getLeagueMembershipRepository
} from '@/lib/di-container';
import { LeagueDriverSeasonStatsPresenter } from '@/lib/presenters/LeagueDriverSeasonStatsPresenter'; import { LeagueDriverSeasonStatsPresenter } from '@/lib/presenters/LeagueDriverSeasonStatsPresenter';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';

View File

@@ -8,15 +8,6 @@ import Button from '@/components/ui/Button';
import { ReviewProtestModal } from '@/components/leagues/ReviewProtestModal'; import { ReviewProtestModal } from '@/components/leagues/ReviewProtestModal';
import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal'; import QuickPenaltyModal from '@/components/leagues/QuickPenaltyModal';
import PenaltyFAB from '@/components/leagues/PenaltyFAB'; import PenaltyFAB from '@/components/leagues/PenaltyFAB';
import {
getRaceRepository,
getProtestRepository,
getDriverRepository,
getLeagueMembershipRepository,
getReviewProtestUseCase,
getApplyPenaltyUseCase,
getPenaltyRepository
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import type { Protest } from '@core/racing/domain/entities/Protest'; import type { Protest } from '@core/racing/domain/entities/Protest';

View File

@@ -5,16 +5,6 @@ import { useParams, useRouter } from 'next/navigation';
import Link from 'next/link'; import Link from 'next/link';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import {
getProtestRepository,
getRaceRepository,
getDriverRepository,
getLeagueMembershipRepository,
getReviewProtestUseCase,
getApplyPenaltyUseCase,
getRequestProtestDefenseUseCase,
getSendNotificationUseCase
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import type { Protest } from '@core/racing/domain/entities/Protest'; import type { Protest } from '@core/racing/domain/entities/Protest';

View File

@@ -32,7 +32,7 @@ import Input from '@/components/ui/Input';
import Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import type { LeagueSummaryViewModel } from '@core/racing/application/presenters/IAllLeaguesWithCapacityAndScoringPresenter'; import type { LeagueSummaryViewModel } from '@core/racing/application/presenters/IAllLeaguesWithCapacityAndScoringPresenter';
import { AllLeaguesWithCapacityAndScoringPresenter } from '@/lib/presenters/AllLeaguesWithCapacityAndScoringPresenter'; import { AllLeaguesWithCapacityAndScoringPresenter } from '@/lib/presenters/AllLeaguesWithCapacityAndScoringPresenter';
import { getGetAllLeaguesWithCapacityAndScoringUseCase } from '@/lib/di-container';
// ============================================================================ // ============================================================================
// TYPES // TYPES

View File

@@ -1,5 +1,4 @@
import { redirect } from 'next/navigation'; import { redirect } from 'next/navigation';
import { getAuthService } from '@/lib/auth';
import OnboardingWizard from '@/components/onboarding/OnboardingWizard'; import OnboardingWizard from '@/components/onboarding/OnboardingWizard';
export const dynamic = 'force-dynamic'; export const dynamic = 'force-dynamic';

View File

@@ -1,7 +1,6 @@
import { redirect } from 'next/navigation'; import { redirect } from 'next/navigation';
import { getAppMode } from '@/lib/mode'; import { getAppMode } from '@/lib/mode';
import { getAuthService } from '@/lib/auth';
import Hero from '@/components/landing/Hero'; import Hero from '@/components/landing/Hero';
import AlternatingSection from '@/components/landing/AlternatingSection'; import AlternatingSection from '@/components/landing/AlternatingSection';
import FeatureGrid from '@/components/landing/FeatureGrid'; import FeatureGrid from '@/components/landing/FeatureGrid';
@@ -15,23 +14,19 @@ import SimPlatformMockup from '@/components/mockups/SimPlatformMockup';
import MockupStack from '@/components/ui/MockupStack'; import MockupStack from '@/components/ui/MockupStack';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import {
topLeagues,
teams,
getUpcomingRaces,
} from '@core/testing-support';
export default async function HomePage() { export default async function HomePage() {
const authService = getAuthService(); const session = null; // TODO
const session = await authService.getCurrentSession();
if (session) { if (session) {
redirect('/dashboard'); redirect('/dashboard');
} }
const mode = getAppMode(); const mode = getAppMode();
const isAlpha = mode === 'alpha'; const isAlpha = mode === 'alpha';
const upcomingRaces = getUpcomingRaces(3); // const upcomingRaces = getUpcomingRaces(3);
const upcomingRaces = []; // TODO
const topLeagues = []; // TODO
const teams = []; // TODO
return ( return (
<main className="min-h-screen"> <main className="min-h-screen">

View File

@@ -4,7 +4,6 @@ import { useEffect, useState } from 'react';
import Link from 'next/link'; import Link from 'next/link';
import Card from '@/components/ui/Card'; import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import { getLeagueRepository, getLeagueMembershipRepository } from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
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';

View File

@@ -34,11 +34,6 @@ import {
Percent, Percent,
Activity, Activity,
} from 'lucide-react'; } from 'lucide-react';
import {
getGetProfileOverviewUseCase,
getImageService,
getUpdateDriverProfileUseCase,
} from '@/lib/di-container';
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import type { import type {
ProfileOverviewViewModel, ProfileOverviewViewModel,

View File

@@ -6,16 +6,7 @@ import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; 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 {
getGetPendingSponsorshipRequestsUseCase,
getAcceptSponsorshipRequestUseCase,
getRejectSponsorshipRequestUseCase,
getDriverRepository,
getLeagueRepository,
getTeamRepository,
getLeagueMembershipRepository,
getTeamMembershipRepository,
} from '@/lib/di-container';
import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter'; import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';

View File

@@ -8,7 +8,7 @@ import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; 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, { useSponsorMode, MetricBuilders, SlotTemplates } from '@/components/sponsors/SponsorInsightsCard';
import { getImageService } from '@/lib/di-container';
import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter'; import { TeamMembersPresenter } from '@/lib/presenters/TeamMembersPresenter';
import { TeamDetailsPresenter } from '@/lib/presenters/TeamDetailsPresenter'; import { TeamDetailsPresenter } from '@/lib/presenters/TeamDetailsPresenter';
import type { TeamDetailsViewModel } from '@core/racing/application/presenters/ITeamDetailsPresenter'; import type { TeamDetailsViewModel } from '@core/racing/application/presenters/ITeamDetailsPresenter';
@@ -16,11 +16,7 @@ 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 TeamAdmin from '@/components/teams/TeamAdmin';
import JoinTeamButton from '@/components/teams/JoinTeamButton'; import JoinTeamButton from '@/components/teams/JoinTeamButton';
import {
getGetTeamDetailsUseCase,
getGetTeamMembersUseCase,
getTeamMembershipRepository,
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { Users, Trophy, TrendingUp, Star, Zap } from 'lucide-react'; import { Users, Trophy, TrendingUp, Star, Zap } from 'lucide-react';

View File

@@ -22,7 +22,6 @@ import {
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 Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import { getGetTeamsLeaderboardUseCase } from '@/lib/di-container';
import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter'; import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter';
import type { import type {
TeamLeaderboardItemViewModel, TeamLeaderboardItemViewModel,

View File

@@ -28,7 +28,6 @@ import Card from '@/components/ui/Card';
import Input from '@/components/ui/Input'; import Input from '@/components/ui/Input';
import Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import CreateTeamForm from '@/components/teams/CreateTeamForm'; import CreateTeamForm from '@/components/teams/CreateTeamForm';
import { getGetTeamsLeaderboardUseCase } from '@/lib/di-container';
import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter'; import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter';
import type { TeamLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/ITeamsLeaderboardPresenter'; import type { TeamLeaderboardItemViewModel, SkillLevel } from '@core/racing/application/presenters/ITeamsLeaderboardPresenter';

View File

@@ -3,7 +3,6 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { getSendNotificationUseCase, getRaceRepository, getLeagueRepository } from '@/lib/di-container';
import type { NotificationUrgency } from '@core/notifications/application'; import type { NotificationUrgency } from '@core/notifications/application';
import { import {
Bell, Bell,
@@ -182,135 +181,135 @@ export default function DevToolbar() {
return null; return null;
} }
const handleSendNotification = async () => { // const handleSendNotification = async () => {
setSending(true); // setSending(true);
try { // try {
const sendNotification = getSendNotificationUseCase(); // const sendNotification = getSendNotificationUseCase();
const raceRepository = getRaceRepository(); // const raceRepository = getRaceRepository();
const leagueRepository = getLeagueRepository(); // const leagueRepository = getLeagueRepository();
const [allRaces, allLeagues] = await Promise.all([ // const [allRaces, allLeagues] = await Promise.all([
raceRepository.findAll(), // raceRepository.findAll(),
leagueRepository.findAll(), // leagueRepository.findAll(),
]); // ]);
const completedRaces = allRaces.filter((race) => race.status === 'completed'); // const completedRaces = allRaces.filter((race) => race.status === 'completed');
const scheduledRaces = allRaces.filter((race) => race.status === 'scheduled'); // const scheduledRaces = allRaces.filter((race) => race.status === 'scheduled');
const primaryRace = completedRaces[0] ?? allRaces[0]; // const primaryRace = completedRaces[0] ?? allRaces[0];
const secondaryRace = scheduledRaces[0] ?? allRaces[1] ?? primaryRace; // const secondaryRace = scheduledRaces[0] ?? allRaces[1] ?? primaryRace;
const primaryLeague = allLeagues[0]; // const primaryLeague = allLeagues[0];
const notificationDeadline = // const notificationDeadline =
selectedUrgency === 'modal' // selectedUrgency === 'modal'
? new Date(Date.now() + 48 * 60 * 60 * 1000) // ? new Date(Date.now() + 48 * 60 * 60 * 1000)
: undefined; // : undefined;
let title: string; // let title: string;
let body: string; // let body: string;
let notificationType: 'protest_filed' | 'protest_defense_requested' | 'protest_vote_required' | 'race_performance_summary' | 'race_final_results'; // let notificationType: 'protest_filed' | 'protest_defense_requested' | 'protest_vote_required' | 'race_performance_summary' | 'race_final_results';
let actionUrl: string; // let actionUrl: string;
switch (selectedType) { // switch (selectedType) {
case 'protest_filed': { // case 'protest_filed': {
const raceId = primaryRace?.id; // const raceId = primaryRace?.id;
title = '🚨 Protest Filed Against You'; // title = '🚨 Protest Filed Against You';
body = // body =
'A protest has been filed against you for unsafe rejoining during a recent race. Please review the incident details.'; // 'A protest has been filed against you for unsafe rejoining during a recent race. Please review the incident details.';
notificationType = 'protest_filed'; // notificationType = 'protest_filed';
actionUrl = raceId ? `/races/${raceId}/stewarding` : '/races'; // actionUrl = raceId ? `/races/${raceId}/stewarding` : '/races';
break; // break;
} // }
case 'defense_requested': { // case 'defense_requested': {
const raceId = secondaryRace?.id ?? primaryRace?.id; // const raceId = secondaryRace?.id ?? primaryRace?.id;
title = '⚖️ Defense Requested'; // title = '⚖️ Defense Requested';
body = // body =
'A steward has requested your defense regarding a recent incident. Please provide your side of the story within 48 hours.'; // 'A steward has requested your defense regarding a recent incident. Please provide your side of the story within 48 hours.';
notificationType = 'protest_defense_requested'; // notificationType = 'protest_defense_requested';
actionUrl = raceId ? `/races/${raceId}/stewarding` : '/races'; // actionUrl = raceId ? `/races/${raceId}/stewarding` : '/races';
break; // break;
} // }
case 'vote_required': { // case 'vote_required': {
const leagueId = primaryLeague?.id; // const leagueId = primaryLeague?.id;
title = '🗳️ Your Vote Required'; // title = '🗳️ Your Vote Required';
body = // body =
'As a league steward, you are required to vote on an open protest. Please review the case and cast your vote.'; // 'As a league steward, you are required to vote on an open protest. Please review the case and cast your vote.';
notificationType = 'protest_vote_required'; // notificationType = 'protest_vote_required';
actionUrl = leagueId ? `/leagues/${leagueId}/stewarding` : '/leagues'; // actionUrl = leagueId ? `/leagues/${leagueId}/stewarding` : '/leagues';
break; // break;
} // }
case 'race_performance_summary': { // case 'race_performance_summary': {
const raceId = primaryRace?.id; // const raceId = primaryRace?.id;
const leagueId = primaryLeague?.id; // const leagueId = primaryLeague?.id;
title = '🏁 Race Complete: Performance Summary'; // title = '🏁 Race Complete: Performance Summary';
body = // body =
'Your Monza Grand Prix race is finished! You finished P1 with 0 incidents. Provisional rating: +25 points. View full results and standings.'; // 'Your Monza Grand Prix race is finished! You finished P1 with 0 incidents. Provisional rating: +25 points. View full results and standings.';
notificationType = 'race_performance_summary'; // notificationType = 'race_performance_summary';
actionUrl = raceId ? `/races/${raceId}` : '/races'; // actionUrl = raceId ? `/races/${raceId}` : '/races';
break; // break;
} // }
case 'race_final_results': { // case 'race_final_results': {
const leagueId = primaryLeague?.id; // const leagueId = primaryLeague?.id;
title = '🏆 Final Results: Monza Grand Prix'; // title = '🏆 Final Results: Monza Grand Prix';
body = // body =
'Stewarding is now closed. Your final result: P1 (+25 rating). No penalties were applied. View championship standings.'; // 'Stewarding is now closed. Your final result: P1 (+25 rating). No penalties were applied. View championship standings.';
notificationType = 'race_final_results'; // notificationType = 'race_final_results';
actionUrl = leagueId ? `/leagues/${leagueId}/standings` : '/leagues'; // actionUrl = leagueId ? `/leagues/${leagueId}/standings` : '/leagues';
break; // break;
} // }
} // }
const actions = // const actions =
selectedUrgency === 'modal' // selectedUrgency === 'modal'
? selectedType.startsWith('race_') // ? selectedType.startsWith('race_')
? [ // ? [
{ label: selectedType === 'race_performance_summary' ? '🏁 View Race Results' : '🏆 View Standings', type: 'primary' as const, href: actionUrl, actionId: 'view' }, // { label: selectedType === 'race_performance_summary' ? '🏁 View Race Results' : '🏆 View Standings', type: 'primary' as const, href: actionUrl, actionId: 'view' },
{ label: '🎉 Share Achievement', type: 'secondary' as const, actionId: 'share' }, // { label: '🎉 Share Achievement', type: 'secondary' as const, actionId: 'share' },
] // ]
: [ // : [
{ label: 'View Protest', type: 'primary' as const, href: actionUrl, actionId: 'view' }, // { label: 'View Protest', type: 'primary' as const, href: actionUrl, actionId: 'view' },
{ label: 'Dismiss', type: 'secondary' as const, actionId: 'dismiss' }, // { label: 'Dismiss', type: 'secondary' as const, actionId: 'dismiss' },
] // ]
: []; // : [];
await sendNotification.execute({ // await sendNotification.execute({
recipientId: currentDriverId, // recipientId: currentDriverId,
type: notificationType, // type: notificationType,
title, // title,
body, // body,
actionUrl, // actionUrl,
urgency: selectedUrgency as NotificationUrgency, // urgency: selectedUrgency as NotificationUrgency,
requiresResponse: selectedUrgency === 'modal' && !selectedType.startsWith('race_'), // requiresResponse: selectedUrgency === 'modal' && !selectedType.startsWith('race_'),
actions, // actions,
data: { // data: {
...(selectedType.startsWith('protest_') ? { // ...(selectedType.startsWith('protest_') ? {
protestId: `demo-protest-${Date.now()}`, // protestId: `demo-protest-${Date.now()}`,
} : {}), // } : {}),
...(selectedType.startsWith('race_') ? { // ...(selectedType.startsWith('race_') ? {
raceEventId: `demo-race-event-${Date.now()}`, // raceEventId: `demo-race-event-${Date.now()}`,
sessionId: `demo-session-${Date.now()}`, // sessionId: `demo-session-${Date.now()}`,
position: 1, // position: 1,
positionChange: 0, // positionChange: 0,
incidents: 0, // incidents: 0,
provisionalRatingChange: 25, // provisionalRatingChange: 25,
finalRatingChange: 25, // finalRatingChange: 25,
hadPenaltiesApplied: false, // hadPenaltiesApplied: false,
} : {}), // } : {}),
raceId: primaryRace?.id ?? '', // raceId: primaryRace?.id ?? '',
leagueId: primaryLeague?.id ?? '', // leagueId: primaryLeague?.id ?? '',
...(notificationDeadline && selectedType.startsWith('protest_') ? { deadline: notificationDeadline } : {}), // ...(notificationDeadline && selectedType.startsWith('protest_') ? { deadline: notificationDeadline } : {}),
}, // },
}); // });
setLastSent(`${selectedType}-${selectedUrgency}`); // setLastSent(`${selectedType}-${selectedUrgency}`);
setTimeout(() => setLastSent(null), 3000); // setTimeout(() => setLastSent(null), 3000);
} catch (error) { // } catch (error) {
console.error('Failed to send demo notification:', error); // console.error('Failed to send demo notification:', error);
} finally { // } finally {
setSending(false); // setSending(false);
} // }
}; // };
if (isMinimized) { if (isMinimized) {
return ( return (

View File

@@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation';
import Input from '../ui/Input'; import Input from '../ui/Input';
import Button from '../ui/Button'; import Button from '../ui/Button';
import { Driver } from '@core/racing'; import { Driver } from '@core/racing';
import { getDriverRepository } from '../../lib/di-container';
interface FormErrors { interface FormErrors {
name?: string; name?: string;

View File

@@ -1,7 +1,6 @@
import Link from 'next/link'; import Link from 'next/link';
import Image from 'next/image'; import Image from 'next/image';
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import { getImageService } from '@/lib/di-container';
export interface DriverIdentityProps { export interface DriverIdentityProps {
driver: DriverDTO; driver: DriverDTO;

View File

@@ -8,7 +8,6 @@ import CareerHighlights from './CareerHighlights';
import DriverRankings from './DriverRankings'; import DriverRankings from './DriverRankings';
import PerformanceMetrics from './PerformanceMetrics'; import PerformanceMetrics from './PerformanceMetrics';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { getLeagueRankings, getGetDriverTeamUseCase, getGetProfileOverviewUseCase } from '@/lib/di-container';
import { DriverTeamPresenter } from '@/lib/presenters/DriverTeamPresenter'; import { DriverTeamPresenter } from '@/lib/presenters/DriverTeamPresenter';
import { getPrimaryLeagueIdForDriver } from '@/lib/leagueMembership'; import { getPrimaryLeagueIdForDriver } from '@/lib/leagueMembership';
import type { ProfileOverviewViewModel } from '@core/racing/application/presenters/IProfileOverviewPresenter'; import type { ProfileOverviewViewModel } from '@core/racing/application/presenters/IProfileOverviewPresenter';

View File

@@ -4,7 +4,6 @@ import { useState, useEffect } from 'react';
import Card from '../ui/Card'; import Card from '../ui/Card';
import Button from '../ui/Button'; import Button from '../ui/Button';
import RaceResultCard from '../races/RaceResultCard'; import RaceResultCard from '../races/RaceResultCard';
import { getRaceRepository, getLeagueRepository, getResultRepository } from '@/lib/di-container';
import { Race } from '@core/racing/domain/entities/Race'; import { Race } from '@core/racing/domain/entities/Race';
import { Result } from '@core/racing/domain/entities/Result'; import { Result } from '@core/racing/domain/entities/Result';
import { League } from '@core/racing/domain/entities/League'; import { League } from '@core/racing/domain/entities/League';

View File

@@ -2,7 +2,6 @@
import Card from '../ui/Card'; import Card from '../ui/Card';
import RankBadge from './RankBadge'; import RankBadge from './RankBadge';
import { getLeagueRankings, getGetProfileOverviewUseCase } from '@/lib/di-container';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { getPrimaryLeagueIdForDriver } from '@/lib/leagueMembership'; import { getPrimaryLeagueIdForDriver } from '@/lib/leagueMembership';
import type { ProfileOverviewViewModel } from '@core/racing/application/presenters/IProfileOverviewPresenter'; import type { ProfileOverviewViewModel } from '@core/racing/application/presenters/IProfileOverviewPresenter';

View File

@@ -3,7 +3,6 @@ import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Image from 'next/image'; import Image from 'next/image';
import type { FeedItemDTO } from '@core/social/application/dto/FeedItemDTO'; import type { FeedItemDTO } from '@core/social/application/dto/FeedItemDTO';
import { getDriverRepository, getImageService } from '@/lib/di-container';
function timeAgo(timestamp: Date | string): string { function timeAgo(timestamp: Date | string): string {
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp; const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;

View File

@@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation';
import Input from '../ui/Input'; import Input from '../ui/Input';
import Button from '../ui/Button'; import Button from '../ui/Button';
import { League } from '@core/racing/domain/entities/League'; import { League } from '@core/racing/domain/entities/League';
import { getLeagueRepository, getDriverRepository } from '../../lib/di-container';
interface FormErrors { interface FormErrors {
name?: string; name?: string;

View File

@@ -22,9 +22,7 @@ import Button from '@/components/ui/Button';
import Heading from '@/components/ui/Heading'; import Heading from '@/components/ui/Heading';
import LeagueReviewSummary from '@/components/leagues/LeagueReviewSummary'; import LeagueReviewSummary from '@/components/leagues/LeagueReviewSummary';
import Input from '@/components/ui/Input'; import Input from '@/components/ui/Input';
import {
getListLeagueScoringPresetsQuery,
} from '@/lib/di-container';
import { import {
validateLeagueWizardStep, validateLeagueWizardStep,
validateAllLeagueWizardSteps, validateAllLeagueWizardSteps,

View File

@@ -4,7 +4,6 @@ import { useState } from 'react';
import Button from '../ui/Button'; import Button from '../ui/Button';
import { getMembership, type MembershipStatus } from '@/lib/leagueMembership'; import { getMembership, type MembershipStatus } from '@/lib/leagueMembership';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import { getJoinLeagueUseCase, getLeagueMembershipRepository } from '@/lib/di-container';
interface JoinLeagueButtonProps { interface JoinLeagueButtonProps {
leagueId: string; leagueId: string;

View File

@@ -3,7 +3,6 @@
import { Calendar, Award, UserPlus, UserMinus, Shield, Flag, AlertTriangle } from 'lucide-react'; import { Calendar, Award, UserPlus, UserMinus, Shield, Flag, AlertTriangle } from 'lucide-react';
import { Race, Penalty } from '@core/racing'; import { Race, Penalty } from '@core/racing';
import type { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership'; import type { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
import { getDriverRepository, getPenaltyRepository, getRaceRepository } from '@/lib/di-container';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import type { Driver } from '@core/racing'; import type { Driver } from '@core/racing';

View File

@@ -14,7 +14,6 @@ import {
} from 'lucide-react'; } from 'lucide-react';
import type { LeagueSummaryViewModel } from '@core/racing/application/presenters/IAllLeaguesWithCapacityAndScoringPresenter'; import type { LeagueSummaryViewModel } from '@core/racing/application/presenters/IAllLeaguesWithCapacityAndScoringPresenter';
import { getLeagueCoverClasses } from '@/lib/leagueCovers'; import { getLeagueCoverClasses } from '@/lib/leagueCovers';
import { getImageService } from '@/lib/di-container';
interface LeagueCardProps { interface LeagueCardProps {
league: LeagueSummaryViewModel; league: LeagueSummaryViewModel;

View File

@@ -5,12 +5,7 @@ import Link from 'next/link';
import Image from 'next/image'; import Image from 'next/image';
import MembershipStatus from '@/components/leagues/MembershipStatus'; import MembershipStatus from '@/components/leagues/MembershipStatus';
import FeatureLimitationTooltip from '@/components/alpha/FeatureLimitationTooltip'; import FeatureLimitationTooltip from '@/components/alpha/FeatureLimitationTooltip';
import {
getDriverRepository,
getDriverStats,
getAllDriverRankings,
getImageService,
} from '@/lib/di-container';
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'; import DriverSummaryPill from '@/components/profile/DriverSummaryPill';

View File

@@ -4,7 +4,6 @@ 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 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 { getDriverRepository, getDriverStats } from '@/lib/di-container';
import { import {
getLeagueMembers, getLeagueMembers,
type LeagueMembership, type LeagueMembership,

View File

@@ -5,12 +5,7 @@ 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 { DollarSign, Star, Award, Plus, X, Bell } from 'lucide-react';
import PendingSponsorshipRequests, { type PendingRequestDTO } from '../sponsors/PendingSponsorshipRequests'; import PendingSponsorshipRequests, { type PendingRequestDTO } from '../sponsors/PendingSponsorshipRequests';
import {
getGetPendingSponsorshipRequestsUseCase,
getAcceptSponsorshipRequestUseCase,
getRejectSponsorshipRequestUseCase,
getSeasonRepository,
} from '@/lib/di-container';
import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter'; import { PendingSponsorshipRequestsPresenter } from '@/lib/presenters/PendingSponsorshipRequestsPresenter';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';

View File

@@ -2,7 +2,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { getQuickPenaltyUseCase } from '@/lib/di-container';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import { AlertTriangle, Clock, Flag, Zap } from 'lucide-react'; import { AlertTriangle, Clock, Flag, Zap } from 'lucide-react';

View File

@@ -8,8 +8,6 @@ import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import type { LeagueDriverSeasonStatsDTO } from '@core/racing/application/dto/LeagueDriverSeasonStatsDTO'; import type { LeagueDriverSeasonStatsDTO } from '@core/racing/application/dto/LeagueDriverSeasonStatsDTO';
import type { LeagueMembership, MembershipRole } from '@/lib/leagueMembership'; import type { LeagueMembership, MembershipRole } from '@/lib/leagueMembership';
import { getLeagueRoleDisplay } from '@/lib/leagueRoles'; import { getLeagueRoleDisplay } from '@/lib/leagueRoles';
import { getDriverStats } from '@/lib/di-container';
import { getImageService } from '@/lib/di-container';
import CountryFlag from '@/components/ui/CountryFlag'; import CountryFlag from '@/components/ui/CountryFlag';
// Position background colors // Position background colors

View File

@@ -4,10 +4,6 @@ import React, { useState, useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import Link from 'next/link'; import Link from 'next/link';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import {
getNotificationRepository,
getMarkNotificationReadUseCase,
} from '@/lib/di-container';
import type { Notification } from '@core/notifications/application'; import type { Notification } from '@core/notifications/application';
import { import {
Bell, Bell,
@@ -52,23 +48,24 @@ export default function NotificationCenter() {
const currentDriverId = useEffectiveDriverId(); const currentDriverId = useEffectiveDriverId();
// Polling for new notifications // Polling for new notifications
useEffect(() => { // TODO
const loadNotifications = async () => { // useEffect(() => {
try { // const loadNotifications = async () => {
const repo = getNotificationRepository(); // try {
const allNotifications = await repo.findByRecipientId(currentDriverId); // const repo = getNotificationRepository();
setNotifications(allNotifications); // const allNotifications = await repo.findByRecipientId(currentDriverId);
} catch (error) { // setNotifications(allNotifications);
console.error('Failed to load notifications:', error); // } catch (error) {
} // console.error('Failed to load notifications:', error);
}; // }
// };
loadNotifications(); // loadNotifications();
// Poll every 5 seconds // // Poll every 5 seconds
const interval = setInterval(loadNotifications, 5000); // const interval = setInterval(loadNotifications, 5000);
return () => clearInterval(interval); // return () => clearInterval(interval);
}, [currentDriverId]); // }, [currentDriverId]);
// Close panel when clicking outside // Close panel when clicking outside
useEffect(() => { useEffect(() => {

View File

@@ -2,10 +2,7 @@
import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'; import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
import {
getNotificationRepository,
getMarkNotificationReadUseCase,
} from '@/lib/di-container';
import type { Notification } from '@core/notifications/application'; import type { Notification } from '@core/notifications/application';
import ToastNotification from './ToastNotification'; import ToastNotification from './ToastNotification';
import ModalNotification from './ModalNotification'; import ModalNotification from './ModalNotification';
@@ -44,45 +41,46 @@ export default function NotificationProvider({ children }: NotificationProviderP
const currentDriverId = useEffectiveDriverId(); const currentDriverId = useEffectiveDriverId();
// Poll for new notifications // Poll for new notifications
useEffect(() => { // TODO
const loadNotifications = async () => { // useEffect(() => {
try { // const loadNotifications = async () => {
const repo = getNotificationRepository(); // try {
const allNotifications = await repo.findByRecipientId(currentDriverId); // const repo = getNotificationRepository();
setNotifications(allNotifications); // const allNotifications = await repo.findByRecipientId(currentDriverId);
// setNotifications(allNotifications);
// Check for new notifications that need toast/modal display // // Check for new notifications that need toast/modal display
allNotifications.forEach((notification) => { // allNotifications.forEach((notification) => {
// Check both unread and action_required status for modals // // Check both unread and action_required status for modals
const shouldDisplay = (notification.isUnread() || notification.isActionRequired()) && // const shouldDisplay = (notification.isUnread() || notification.isActionRequired()) &&
!seenNotificationIds.has(notification.id); // !seenNotificationIds.has(notification.id);
if (shouldDisplay) { // if (shouldDisplay) {
// Mark as seen to prevent duplicate displays // // Mark as seen to prevent duplicate displays
setSeenNotificationIds((prev) => new Set([...prev, notification.id])); // setSeenNotificationIds((prev) => new Set([...prev, notification.id]));
// Handle based on urgency // // Handle based on urgency
if (notification.isModal()) { // if (notification.isModal()) {
// Modal takes priority - show immediately // // Modal takes priority - show immediately
setModalNotification(notification); // setModalNotification(notification);
} else if (notification.isToast()) { // } else if (notification.isToast()) {
// Add to toast queue // // Add to toast queue
setToastNotifications((prev) => [...prev, notification]); // setToastNotifications((prev) => [...prev, notification]);
} // }
// Silent notifications just appear in the notification center // // Silent notifications just appear in the notification center
} // }
}); // });
} catch (error) { // } catch (error) {
console.error('Failed to load notifications:', error); // console.error('Failed to load notifications:', error);
} // }
}; // };
loadNotifications(); // loadNotifications();
// Poll every 2 seconds for responsiveness // // Poll every 2 seconds for responsiveness
const interval = setInterval(loadNotifications, 2000); // const interval = setInterval(loadNotifications, 2000);
return () => clearInterval(interval); // return () => clearInterval(interval);
}, [currentDriverId, seenNotificationIds]); // }, [currentDriverId, seenNotificationIds]);
// Prevent body scroll when modal is open // Prevent body scroll when modal is open
useEffect(() => { useEffect(() => {

View File

@@ -4,7 +4,6 @@ import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import DriverRating from '@/components/profile/DriverRatingPill'; import DriverRating from '@/components/profile/DriverRatingPill';
import { getImageService } from '@/lib/di-container';
export interface DriverSummaryPillProps { export interface DriverSummaryPillProps {
driver: DriverDTO; driver: DriverDTO;

View File

@@ -3,7 +3,6 @@
import Image from 'next/image'; import Image from 'next/image';
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO'; import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import Button from '../ui/Button'; import Button from '../ui/Button';
import { getImageService } from '@/lib/di-container';
import DriverRatingPill from '@/components/profile/DriverRatingPill'; import DriverRatingPill from '@/components/profile/DriverRatingPill';
import CountryFlag from '@/components/ui/CountryFlag'; import CountryFlag from '@/components/ui/CountryFlag';

View File

@@ -4,13 +4,7 @@ import Link from 'next/link';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import { LogOut, Settings, Star, Paintbrush, Building2, BarChart3, Megaphone, CreditCard, Handshake } from 'lucide-react'; import { LogOut, Settings, Star, Paintbrush, Building2, BarChart3, Megaphone, CreditCard, Handshake } from 'lucide-react';
import { useAuth } from '@/lib/auth/AuthContext'; import { useAuth } from '@/lib/auth/AuthContext';
import {
getDriverStats,
getLeagueRankings,
getAllDriverRankings,
getDriverRepository,
getImageService,
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
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';

View File

@@ -3,7 +3,6 @@
import { useState } from 'react'; import { useState } from 'react';
import Modal from '@/components/ui/Modal'; import Modal from '@/components/ui/Modal';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import { getFileProtestUseCase } from '@/lib/di-container';
import type { ProtestIncident } from '@core/racing/domain/entities/Protest'; import type { ProtestIncident } from '@core/racing/domain/entities/Protest';
import { import {
AlertTriangle, AlertTriangle,

View File

@@ -21,7 +21,6 @@ import {
Check, Check,
Loader2, Loader2,
} from 'lucide-react'; } from 'lucide-react';
import { getApplyForSponsorshipUseCase, getSponsorRepository } from '@/lib/di-container';
// ============================================================================ // ============================================================================
// TYPES // TYPES

View File

@@ -4,7 +4,6 @@ import { useState } from 'react';
import { useRouter } from 'next/navigation'; 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 { getCreateTeamUseCase } from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
interface CreateTeamFormProps { interface CreateTeamFormProps {

View File

@@ -2,11 +2,6 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import {
getJoinTeamUseCase,
getLeaveTeamUseCase,
getTeamMembershipRepository,
} from '@/lib/di-container';
import { useEffectiveDriverId } from '@/lib/currentDriver'; import { useEffectiveDriverId } from '@/lib/currentDriver';
type TeamMembershipStatus = 'active' | 'pending' | 'inactive'; type TeamMembershipStatus = 'active' | 'pending' | 'inactive';

View File

@@ -16,7 +16,6 @@ import {
Globe, Globe,
Languages, Languages,
} from 'lucide-react'; } from 'lucide-react';
import { getImageService } from '@/lib/di-container';
interface TeamCardProps { interface TeamCardProps {
id: string; id: string;

View File

@@ -2,7 +2,6 @@
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import Image from 'next/image'; import Image from 'next/image';
import { getImageService } from '@/lib/di-container';
export interface TeamLadderRowProps { export interface TeamLadderRowProps {
rank: number; rank: number;

View File

@@ -24,7 +24,7 @@
"docker:prod:down": "docker-compose -f docker-compose.prod.yml down", "docker:prod:down": "docker-compose -f docker-compose.prod.yml down",
"docker:prod:logs": "docker-compose -f docker-compose.prod.yml logs -f", "docker:prod:logs": "docker-compose -f docker-compose.prod.yml logs -f",
"docker:prod:clean": "docker-compose -f docker-compose.prod.yml down -v", "docker:prod:clean": "docker-compose -f docker-compose.prod.yml down -v",
"api:build": "npm run build --workspace=@core/api", "api:build": "npm run build --workspace=@gridpilot/api",
"test": "vitest run \"$@\"", "test": "vitest run \"$@\"",
"test:unit": "vitest run tests/unit", "test:unit": "vitest run tests/unit",
"test:integration": "vitest run tests/integration", "test:integration": "vitest run tests/integration",
@@ -39,16 +39,16 @@
"test:companion-hosted": "vitest run --config vitest.e2e.config.ts tests/e2e/companion/companion-ui-full-workflow.e2e.test.ts", "test:companion-hosted": "vitest run --config vitest.e2e.config.ts tests/e2e/companion/companion-ui-full-workflow.e2e.test.ts",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"test:types": "tsc --noEmit -p tsconfig.tests.json", "test:types": "tsc --noEmit -p tsconfig.tests.json",
"companion:dev": "npm run dev --workspace=@core/companion", "companion:dev": "npm run dev --workspace=@gridpilot/companion",
"companion:build": "npm run build --workspace=@core/companion", "companion:build": "npm run build --workspace=@gridpilot/companion",
"companion:start": "npm run start --workspace=@core/companion", "companion:start": "npm run start --workspace=@gridpilot/companion",
"env:website:merge": "node scripts/merge-website-env.js", "env:website:merge": "node scripts/merge-website-env.js",
"website:dev": "npm run env:website:merge && npm run dev --workspace=@core/website", "website:dev": "npm run env:website:merge && npm run dev --workspace=@gridpilot/website",
"website:build": "npm run env:website:merge && npm run build --workspace=@core/website", "website:build": "npm run env:website:merge && npm run build --workspace=@gridpilot/website",
"website:start": "npm run start --workspace=@core/website", "website:start": "npm run start --workspace=@gridpilot/website",
"website:lint": "npm run lint --workspace=@core/website", "website:lint": "npm run lint --workspace=@gridpilot/website",
"website:type-check": "npm run type-check --workspace=@core/website", "website:type-check": "npm run type-check --workspace=@gridpilot/website",
"website:clean": "npm run clean --workspace=@core/website", "website:clean": "npm run clean --workspace=@gridpilot/website",
"deploy:website:preview": "npx vercel deploy --cwd apps/website", "deploy:website:preview": "npx vercel deploy --cwd apps/website",
"deploy:website:prod": "npx vercel deploy --prod", "deploy:website:prod": "npx vercel deploy --prod",
"deploy:website": "npm run deploy:website:prod", "deploy:website": "npm run deploy:website:prod",