website refactor
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
import { notFound } from 'next/navigation';
|
||||
import { PageWrapper } from '@/components/shared/state/PageWrapper';
|
||||
import { RaceDetailTemplate } from '@/templates/RaceDetailTemplate';
|
||||
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';
|
||||
import { RaceDetailPageQuery } from '@/lib/page-queries/races/RaceDetailPageQuery';
|
||||
|
||||
interface RaceDetailPageProps {
|
||||
params: {
|
||||
@@ -19,72 +16,87 @@ export default async function RaceDetailPage({ params }: RaceDetailPageProps) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// 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, '');
|
||||
// Execute PageQuery
|
||||
const result = await RaceDetailPageQuery.execute({ raceId, driverId: '' });
|
||||
|
||||
if (!data) notFound();
|
||||
|
||||
// Transform data for template
|
||||
const templateViewModel = data && data.race ? {
|
||||
race: {
|
||||
id: data.race.id,
|
||||
track: data.race.track,
|
||||
car: data.race.car,
|
||||
scheduledAt: data.race.scheduledAt,
|
||||
status: data.race.status as 'scheduled' | 'running' | 'completed' | 'cancelled',
|
||||
sessionType: data.race.sessionType,
|
||||
},
|
||||
league: data.league ? {
|
||||
id: data.league.id,
|
||||
name: data.league.name,
|
||||
description: data.league.description || undefined,
|
||||
settings: data.league.settings as { maxDrivers: number; qualifyingFormat: string },
|
||||
} : undefined,
|
||||
entryList: data.entryList.map((entry: any) => ({
|
||||
id: entry.id,
|
||||
name: entry.name,
|
||||
avatarUrl: entry.avatarUrl,
|
||||
country: entry.country,
|
||||
rating: entry.rating,
|
||||
isCurrentUser: entry.isCurrentUser,
|
||||
})),
|
||||
registration: {
|
||||
isUserRegistered: data.registration.isUserRegistered,
|
||||
canRegister: data.registration.canRegister,
|
||||
},
|
||||
userResult: data.userResult ? {
|
||||
position: data.userResult.position,
|
||||
startPosition: data.userResult.startPosition,
|
||||
positionChange: data.userResult.positionChange,
|
||||
incidents: data.userResult.incidents,
|
||||
isClean: data.userResult.isClean,
|
||||
isPodium: data.userResult.isPodium,
|
||||
ratingChange: data.userResult.ratingChange,
|
||||
} : undefined,
|
||||
canReopenRace: false, // Not provided by API, default to false
|
||||
} : undefined;
|
||||
if (result.isErr()) {
|
||||
const error = result.getError();
|
||||
|
||||
switch (error) {
|
||||
case 'notFound':
|
||||
notFound();
|
||||
case 'redirect':
|
||||
notFound();
|
||||
default:
|
||||
// Pass error to template via PageWrapper
|
||||
return (
|
||||
<PageWrapper
|
||||
data={null}
|
||||
Template={({ data: _data }) => (
|
||||
<RaceDetailTemplate
|
||||
viewModel={undefined}
|
||||
isLoading={false}
|
||||
error={new Error('Failed to load race details')}
|
||||
onBack={() => {}}
|
||||
onRegister={() => {}}
|
||||
onWithdraw={() => {}}
|
||||
onCancel={() => {}}
|
||||
onReopen={() => {}}
|
||||
onEndRace={() => {}}
|
||||
onFileProtest={() => {}}
|
||||
onResultsClick={() => {}}
|
||||
onStewardingClick={() => {}}
|
||||
onLeagueClick={() => {}}
|
||||
onDriverClick={() => {}}
|
||||
currentDriverId={''}
|
||||
isOwnerOrAdmin={false}
|
||||
showProtestModal={false}
|
||||
setShowProtestModal={() => {}}
|
||||
showEndRaceModal={false}
|
||||
setShowEndRaceModal={() => {}}
|
||||
mutationLoading={{
|
||||
register: false,
|
||||
withdraw: false,
|
||||
cancel: false,
|
||||
reopen: false,
|
||||
complete: false,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
loading={{ variant: 'skeleton', message: 'Loading race details...' }}
|
||||
errorConfig={{ variant: 'full-screen' }}
|
||||
empty={{
|
||||
icon: require('lucide-react').Flag,
|
||||
title: 'Race not found',
|
||||
description: 'The race may have been cancelled or deleted',
|
||||
action: { label: 'Back to Races', onClick: () => {} }
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const viewData = result.unwrap();
|
||||
|
||||
// Convert ViewData to ViewModel for the template
|
||||
// The template expects a ViewModel, so we need to adapt
|
||||
const viewModel = {
|
||||
race: viewData.race,
|
||||
league: viewData.league,
|
||||
entryList: viewData.entryList,
|
||||
registration: viewData.registration,
|
||||
userResult: viewData.userResult,
|
||||
canReopenRace: viewData.canReopenRace,
|
||||
};
|
||||
|
||||
return (
|
||||
<PageWrapper
|
||||
data={data}
|
||||
Template={({ data }) => (
|
||||
data={viewData}
|
||||
Template={({ data: _data }) => (
|
||||
<RaceDetailTemplate
|
||||
viewModel={templateViewModel}
|
||||
viewModel={viewModel}
|
||||
isLoading={false}
|
||||
error={null}
|
||||
// These will be handled client-side in the template or a wrapper
|
||||
onBack={() => {}}
|
||||
onRegister={() => {}}
|
||||
onWithdraw={() => {}}
|
||||
|
||||
Reference in New Issue
Block a user