website refactor
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { notFound } from 'next/navigation';
|
||||
import { PageWrapper } from '@/components/shared/state/PageWrapper';
|
||||
import { RaceDetailTemplate } from '@/templates/RaceDetailTemplate';
|
||||
import { PageDataFetcher } from '@/lib/page/PageDataFetcher';
|
||||
import { RACE_SERVICE_TOKEN } from '@/lib/di/tokens';
|
||||
import type { RaceService } from '@/lib/services/races/RaceService';
|
||||
import type { RaceDetailViewModel } from '@/lib/view-models/RaceDetailViewModel';
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
|
||||
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
||||
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
|
||||
|
||||
interface RaceDetailPageProps {
|
||||
params: {
|
||||
@@ -19,13 +19,20 @@ export default async function RaceDetailPage({ params }: RaceDetailPageProps) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// Fetch initial race data
|
||||
const data = await PageDataFetcher.fetch<RaceService, 'getRaceDetail'>(
|
||||
RACE_SERVICE_TOKEN,
|
||||
'getRaceDetail',
|
||||
raceId,
|
||||
'' // currentDriverId - will be handled client-side for auth
|
||||
);
|
||||
// Manual wiring: create dependencies
|
||||
const baseUrl = getWebsiteApiBaseUrl();
|
||||
const logger = new ConsoleLogger();
|
||||
const errorReporter = new EnhancedErrorReporter(logger, {
|
||||
showUserNotifications: true,
|
||||
logToConsole: true,
|
||||
reportToExternal: process.env.NODE_ENV === 'production',
|
||||
});
|
||||
|
||||
// Create API client
|
||||
const apiClient = new RacesApiClient(baseUrl, errorReporter, logger);
|
||||
|
||||
// Fetch initial race data (empty driverId for now, handled client-side)
|
||||
const data = await apiClient.getDetail(raceId, '');
|
||||
|
||||
if (!data) notFound();
|
||||
|
||||
@@ -66,7 +73,7 @@ export default async function RaceDetailPage({ params }: RaceDetailPageProps) {
|
||||
isPodium: data.userResult.isPodium,
|
||||
ratingChange: data.userResult.ratingChange,
|
||||
} : undefined,
|
||||
canReopenRace: data.canReopenRace,
|
||||
canReopenRace: false, // Not provided by API, default to false
|
||||
} : undefined;
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,15 +4,30 @@ import { useState, useEffect } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { PageWrapper } from '@/components/shared/state/PageWrapper';
|
||||
import { RaceStewardingTemplate, StewardingTab } from '@/templates/RaceStewardingTemplate';
|
||||
import { PageDataFetcher } from '@/lib/page/PageDataFetcher';
|
||||
import { RACE_STEWARDING_SERVICE_TOKEN } from '@/lib/di/tokens';
|
||||
import { RaceStewardingService } from '@/lib/services/races/RaceStewardingService';
|
||||
import type { RaceStewardingViewModel } from '@/lib/view-models/RaceStewardingViewModel';
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { ProtestsApiClient } from '@/lib/api/protests/ProtestsApiClient';
|
||||
import { PenaltiesApiClient } from '@/lib/api/penalties/PenaltiesApiClient';
|
||||
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
|
||||
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
||||
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
|
||||
import { useLeagueMemberships } from "@/lib/hooks/league/useLeagueMemberships";
|
||||
import { useEffectiveDriverId } from "@/lib/hooks/useEffectiveDriverId";
|
||||
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
|
||||
import { Gavel } from 'lucide-react';
|
||||
import type { LeagueMembershipsDTO } from '@/lib/types/generated/LeagueMembershipsDTO';
|
||||
|
||||
// Define the view model structure locally to avoid type issues
|
||||
interface RaceStewardingViewModel {
|
||||
race: any;
|
||||
league: any;
|
||||
protests: any[];
|
||||
penalties: any[];
|
||||
driverMap: Record<string, any>;
|
||||
pendingProtests: any[];
|
||||
resolvedProtests: any[];
|
||||
pendingCount: number;
|
||||
resolvedCount: number;
|
||||
penaltiesCount: number;
|
||||
}
|
||||
|
||||
export default function RaceStewardingPage() {
|
||||
const router = useRouter();
|
||||
@@ -37,12 +52,61 @@ export default function RaceStewardingPage() {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const data = await PageDataFetcher.fetch<RaceStewardingService, 'getRaceStewardingData'>(
|
||||
RACE_STEWARDING_SERVICE_TOKEN,
|
||||
'getRaceStewardingData',
|
||||
raceId,
|
||||
currentDriverId
|
||||
// Manual wiring: create dependencies
|
||||
const baseUrl = getWebsiteApiBaseUrl();
|
||||
const logger = new ConsoleLogger();
|
||||
const errorReporter = new EnhancedErrorReporter(logger, {
|
||||
showUserNotifications: true,
|
||||
logToConsole: true,
|
||||
reportToExternal: process.env.NODE_ENV === 'production',
|
||||
});
|
||||
|
||||
// Create API clients
|
||||
const racesApiClient = new RacesApiClient(baseUrl, errorReporter, logger);
|
||||
const protestsApiClient = new ProtestsApiClient(baseUrl, errorReporter, logger);
|
||||
const penaltiesApiClient = new PenaltiesApiClient(baseUrl, errorReporter, logger);
|
||||
|
||||
// Fetch data in parallel
|
||||
const [raceDetail, protests, penalties] = await Promise.all([
|
||||
racesApiClient.getDetail(raceId, currentDriverId),
|
||||
protestsApiClient.getRaceProtests(raceId),
|
||||
penaltiesApiClient.getRacePenalties(raceId),
|
||||
]);
|
||||
|
||||
// Transform data to match view model structure
|
||||
const data: RaceStewardingViewModel = {
|
||||
race: raceDetail.race,
|
||||
league: raceDetail.league,
|
||||
protests: protests.protests.map(p => ({
|
||||
id: p.id,
|
||||
protestingDriverId: p.protestingDriverId,
|
||||
accusedDriverId: p.accusedDriverId,
|
||||
incident: {
|
||||
lap: p.lap,
|
||||
description: p.description,
|
||||
},
|
||||
filedAt: p.filedAt,
|
||||
status: p.status,
|
||||
})),
|
||||
penalties: penalties.penalties,
|
||||
driverMap: { ...protests.driverMap, ...penalties.driverMap },
|
||||
pendingProtests: [],
|
||||
resolvedProtests: [],
|
||||
pendingCount: 0,
|
||||
resolvedCount: 0,
|
||||
penaltiesCount: 0,
|
||||
};
|
||||
|
||||
// Calculate derived properties
|
||||
data.pendingProtests = data.protests.filter(p => p.status === 'pending' || p.status === 'under_review');
|
||||
data.resolvedProtests = data.protests.filter(p =>
|
||||
p.status === 'upheld' ||
|
||||
p.status === 'dismissed' ||
|
||||
p.status === 'withdrawn'
|
||||
);
|
||||
data.pendingCount = data.pendingProtests.length;
|
||||
data.resolvedCount = data.resolvedProtests.length;
|
||||
data.penaltiesCount = data.penalties.length;
|
||||
|
||||
if (data) {
|
||||
setPageData(data);
|
||||
@@ -93,12 +157,61 @@ export default function RaceStewardingPage() {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const data = await PageDataFetcher.fetch<RaceStewardingService, 'getRaceStewardingData'>(
|
||||
RACE_STEWARDING_SERVICE_TOKEN,
|
||||
'getRaceStewardingData',
|
||||
raceId,
|
||||
currentDriverId
|
||||
// Manual wiring: create dependencies
|
||||
const baseUrl = getWebsiteApiBaseUrl();
|
||||
const logger = new ConsoleLogger();
|
||||
const errorReporter = new EnhancedErrorReporter(logger, {
|
||||
showUserNotifications: true,
|
||||
logToConsole: true,
|
||||
reportToExternal: process.env.NODE_ENV === 'production',
|
||||
});
|
||||
|
||||
// Create API clients
|
||||
const racesApiClient = new RacesApiClient(baseUrl, errorReporter, logger);
|
||||
const protestsApiClient = new ProtestsApiClient(baseUrl, errorReporter, logger);
|
||||
const penaltiesApiClient = new PenaltiesApiClient(baseUrl, errorReporter, logger);
|
||||
|
||||
// Fetch data in parallel
|
||||
const [raceDetail, protests, penalties] = await Promise.all([
|
||||
racesApiClient.getDetail(raceId, currentDriverId),
|
||||
protestsApiClient.getRaceProtests(raceId),
|
||||
penaltiesApiClient.getRacePenalties(raceId),
|
||||
]);
|
||||
|
||||
// Transform data to match view model structure
|
||||
const data: RaceStewardingViewModel = {
|
||||
race: raceDetail.race,
|
||||
league: raceDetail.league,
|
||||
protests: protests.protests.map(p => ({
|
||||
id: p.id,
|
||||
protestingDriverId: p.protestingDriverId,
|
||||
accusedDriverId: p.accusedDriverId,
|
||||
incident: {
|
||||
lap: p.lap,
|
||||
description: p.description,
|
||||
},
|
||||
filedAt: p.filedAt,
|
||||
status: p.status,
|
||||
})),
|
||||
penalties: penalties.penalties,
|
||||
driverMap: { ...protests.driverMap, ...penalties.driverMap },
|
||||
pendingProtests: [],
|
||||
resolvedProtests: [],
|
||||
pendingCount: 0,
|
||||
resolvedCount: 0,
|
||||
penaltiesCount: 0,
|
||||
};
|
||||
|
||||
// Calculate derived properties
|
||||
data.pendingProtests = data.protests.filter(p => p.status === 'pending' || p.status === 'under_review');
|
||||
data.resolvedProtests = data.protests.filter(p =>
|
||||
p.status === 'upheld' ||
|
||||
p.status === 'dismissed' ||
|
||||
p.status === 'withdrawn'
|
||||
);
|
||||
data.pendingCount = data.pendingProtests.length;
|
||||
data.resolvedCount = data.resolvedProtests.length;
|
||||
data.penaltiesCount = data.penalties.length;
|
||||
|
||||
if (data) {
|
||||
setPageData(data);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { RacesTemplate } from '@/templates/RacesTemplate';
|
||||
import { RaceService } from '@/lib/services/races/RaceService';
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
|
||||
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
||||
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
|
||||
|
||||
export default async function Page() {
|
||||
// Create dependencies for API clients
|
||||
// Manual wiring: create dependencies
|
||||
const baseUrl = getWebsiteApiBaseUrl();
|
||||
const logger = new ConsoleLogger();
|
||||
const errorReporter = new EnhancedErrorReporter(logger, {
|
||||
@@ -18,12 +17,10 @@ export default async function Page() {
|
||||
// Create API client
|
||||
const racesApiClient = new RacesApiClient(baseUrl, errorReporter, logger);
|
||||
|
||||
// Create service
|
||||
const service = new RaceService(racesApiClient);
|
||||
// Fetch data
|
||||
const data = await racesApiClient.getPageData();
|
||||
|
||||
const data = await service.getRacesPageData();
|
||||
|
||||
// Transform data for template
|
||||
// Transform races
|
||||
const transformRace = (race: any) => ({
|
||||
id: race.id,
|
||||
track: race.track,
|
||||
@@ -34,16 +31,16 @@ export default async function Page() {
|
||||
leagueId: race.leagueId,
|
||||
leagueName: race.leagueName,
|
||||
strengthOfField: race.strengthOfField ?? undefined,
|
||||
isUpcoming: race.isUpcoming,
|
||||
isLive: race.isLive,
|
||||
isPast: race.isPast,
|
||||
isUpcoming: race.status === 'scheduled',
|
||||
isLive: race.status === 'running',
|
||||
isPast: race.status === 'completed',
|
||||
});
|
||||
|
||||
const races = data.races.map(transformRace);
|
||||
const scheduledRaces = data.scheduledRaces.map(transformRace);
|
||||
const runningRaces = data.runningRaces.map(transformRace);
|
||||
const completedRaces = data.completedRaces.map(transformRace);
|
||||
const totalCount = data.totalCount;
|
||||
const scheduledRaces = races.filter(r => r.isUpcoming);
|
||||
const runningRaces = races.filter(r => r.isLive);
|
||||
const completedRaces = races.filter(r => r.isPast);
|
||||
const totalCount = races.length;
|
||||
|
||||
return <RacesTemplate
|
||||
races={races}
|
||||
|
||||
Reference in New Issue
Block a user