website refactor

This commit is contained in:
2026-01-12 01:01:49 +01:00
parent 5ca6023a5a
commit fefd8d1cd6
294 changed files with 4628 additions and 4991 deletions

View File

@@ -1,95 +1,23 @@
'use client';
import React, { useState, useEffect } from 'react';
import type { DashboardViewData } from './DashboardViewData';
import type { DashboardOverviewViewModelData } from '@/lib/view-models/DashboardOverviewViewModelData';
import { DashboardOverviewViewModel } from '@/lib/view-models/DashboardOverviewViewModel';
import React from 'react';
import type { DashboardViewData } from '@/templates/view-data/DashboardViewData';
import type { DashboardPageDto } from '@/lib/page-queries/page-dtos/DashboardPageDto';
import { DashboardPresenter } from '@/lib/presenters/DashboardPresenter';
import { DashboardTemplate } from '@/templates/DashboardTemplate';
interface DashboardPageClientProps {
initialViewData: DashboardViewData;
dto: DashboardOverviewViewModelData;
pageDto: DashboardPageDto;
}
/**
* Dashboard Page Client Component
*
* Two-phase render:
* 1. Initial SSR: Uses ViewData built directly from DTO (no ViewModel)
* 2. Post-hydration: Instantiates ViewModel and re-renders with enhanced data
*
* Uses Presenter to transform Page DTO into ViewData
* Presenter is deterministic and side-effect free
*/
export function DashboardPageClient({ initialViewData, dto }: DashboardPageClientProps) {
const [viewData, setViewData] = useState<DashboardViewData>(initialViewData);
useEffect(() => {
// Phase 2: After hydration, instantiate ViewModel and enhance data
const viewModel = new DashboardOverviewViewModel(dto);
const enhancedViewData: DashboardViewData = {
currentDriver: {
name: viewModel.currentDriverName,
avatarUrl: viewModel.currentDriverAvatarUrl,
country: viewModel.currentDriverCountry,
rating: viewModel.currentDriverRating,
rank: viewModel.currentDriverRank,
totalRaces: viewModel.currentDriverTotalRaces,
wins: viewModel.currentDriverWins,
podiums: viewModel.currentDriverPodiums,
consistency: viewModel.currentDriverConsistency,
},
nextRace: viewModel.nextRace ? {
id: viewModel.nextRace.id,
track: viewModel.nextRace.track,
car: viewModel.nextRace.car,
scheduledAt: viewModel.nextRace.scheduledAt,
formattedDate: viewModel.nextRace.formattedDate,
formattedTime: viewModel.nextRace.formattedTime,
timeUntil: viewModel.nextRace.timeUntil,
isMyLeague: viewModel.nextRace.isMyLeague,
} : null,
upcomingRaces: viewModel.upcomingRaces.map((race) => ({
id: race.id,
track: race.track,
car: race.car,
scheduledAt: race.scheduledAt,
formattedDate: race.formattedDate,
formattedTime: race.formattedTime,
timeUntil: race.timeUntil,
isMyLeague: race.isMyLeague,
})),
leagueStandings: viewModel.leagueStandings.map((standing) => ({
leagueId: standing.leagueId,
leagueName: standing.leagueName,
position: standing.position,
points: standing.points,
totalDrivers: standing.totalDrivers,
})),
feedItems: viewModel.feedItems.map((item) => ({
id: item.id,
type: item.type,
headline: item.headline,
body: item.body,
timestamp: item.timestamp,
formattedTime: item.formattedTime,
ctaHref: item.ctaHref,
ctaLabel: item.ctaLabel,
})),
friends: viewModel.friends.map((friend) => ({
id: friend.id,
name: friend.name,
avatarUrl: friend.avatarUrl,
country: friend.country,
})),
activeLeaguesCount: viewModel.activeLeaguesCount,
friendCount: viewModel.friendCount,
hasUpcomingRaces: viewModel.hasUpcomingRaces,
hasLeagueStandings: viewModel.hasLeagueStandings,
hasFeedItems: viewModel.hasFeedItems,
hasFriends: viewModel.hasFriends,
};
setViewData(enhancedViewData);
}, [dto]);
export function DashboardPageClient({ pageDto }: DashboardPageClientProps) {
const viewData: DashboardViewData = DashboardPresenter.createViewData(pageDto);
return <DashboardTemplate data={viewData} />;
}
}