website refactor

This commit is contained in:
2026-01-14 10:51:05 +01:00
parent 4522d41aef
commit 0d89ad027e
291 changed files with 6887 additions and 3685 deletions

View File

@@ -1,8 +1,9 @@
'use client';
import { useRouter } from 'next/navigation';
import LeaderboardsTemplate from '@/templates/LeaderboardsTemplate';
import { LeaderboardsTemplate } from '@/templates/LeaderboardsTemplate';
import type { LeaderboardsViewData } from '@/lib/view-data/LeaderboardsViewData';
import { routes } from '@/lib/routing/RouteConfig';
export function LeaderboardsPageWrapper({ data }: { data: LeaderboardsViewData | null }) {
const router = useRouter();
@@ -12,22 +13,22 @@ export function LeaderboardsPageWrapper({ data }: { data: LeaderboardsViewData |
}
const handleDriverClick = (driverId: string) => {
router.push(`/drivers/${driverId}`);
router.push(routes.driver.detail(driverId));
};
const handleTeamClick = (teamId: string) => {
router.push(`/teams/${teamId}`);
router.push(routes.team.detail(teamId));
};
const handleNavigateToDrivers = () => {
router.push('/leaderboards/drivers');
router.push(routes.leaderboards.drivers);
};
const handleNavigateToTeams = () => {
router.push('/teams/leaderboard');
router.push(routes.team.leaderboard);
};
// Transform ViewData to template props
// Transform ViewData to template props (simple field mapping only)
const templateData = {
drivers: data.drivers.map(d => ({
id: d.id,

View File

@@ -1,51 +1,27 @@
import { redirect } from 'next/navigation';
import { notFound, redirect } from 'next/navigation';
import { DriverRankingsPageQuery } from '@/lib/page-queries/page-queries/DriverRankingsPageQuery';
import { DriverRankingsViewDataBuilder } from '@/lib/builders/view-data/DriverRankingsViewDataBuilder';
import { DriverRankingsTemplate } from '@/templates/DriverRankingsTemplate';
// ============================================================================
// MAIN PAGE COMPONENT
// ============================================================================
import { routes } from '@/lib/routing/RouteConfig';
export default async function DriverLeaderboardPage() {
// Execute the page query
const result = await DriverRankingsPageQuery.execute();
// Handle different result statuses
switch (result.status) {
case 'notFound':
redirect('/404');
case 'redirect':
redirect(result.to);
case 'error':
// For now, show empty state. In a real app, you'd pass error to client
return (
<div className="max-w-7xl mx-auto px-4 py-12 text-center">
<div className="text-red-400 mb-4">Error loading driver rankings</div>
<p className="text-gray-400">Please try again later</p>
</div>
);
case 'ok':
const viewData = DriverRankingsViewDataBuilder.build(result.dto);
const hasData = (viewData.drivers?.length ?? 0) > 0;
if (!hasData) {
return (
<DriverRankingsTemplate
viewData={{
drivers: [],
podium: [],
searchQuery: '',
selectedSkill: 'all',
sortBy: 'rank',
showFilters: false,
}}
/>
);
}
return (
<DriverRankingsTemplate viewData={viewData} />
);
if (result.isErr()) {
const error = result.getError();
// Handle different error types
if (error === 'notFound') {
notFound();
} else if (error === 'redirect') {
redirect(routes.public.home);
} else {
// serverError, networkError, unknown, validationError, unauthorized
console.error('Driver rankings error:', error);
notFound();
}
}
// Success
const viewData = result.unwrap();
return <DriverRankingsTemplate viewData={viewData} />;
}

View File

@@ -1,61 +1,27 @@
import { PageWrapper } from '@/components/shared/state/PageWrapper';
import { Trophy } from 'lucide-react';
import { redirect } from 'next/navigation';
import { notFound, redirect } from 'next/navigation';
import { LeaderboardsPageQuery } from '@/lib/page-queries/page-queries/LeaderboardsPageQuery';
import { LeaderboardsViewDataBuilder } from '@/lib/builders/view-data/LeaderboardsViewDataBuilder';
import { LeaderboardsPageWrapper } from './LeaderboardsPageWrapper';
// ============================================================================
// MAIN PAGE COMPONENT
// ============================================================================
import { routes } from '@/lib/routing/RouteConfig';
export default async function LeaderboardsPage() {
// Execute the page query
const result = await LeaderboardsPageQuery.execute();
// Handle different result statuses
switch (result.status) {
case 'notFound':
redirect('/404');
case 'redirect':
redirect(result.to);
case 'error':
// Show empty state with error
return (
<PageWrapper
data={null}
isLoading={false}
error={new Error(result.errorId)}
retry={async () => redirect('/leaderboards')}
Template={LeaderboardsPageWrapper}
loading={{ variant: 'full-screen', message: 'Loading leaderboards...' }}
errorConfig={{ variant: 'full-screen' }}
empty={{
icon: Trophy,
title: 'No leaderboard data',
description: 'There is no leaderboard data available at the moment.',
}}
/>
);
case 'ok':
const viewData = LeaderboardsViewDataBuilder.build(result.dto.drivers, result.dto.teams);
const hasData = (viewData.drivers?.length ?? 0) > 0 || (viewData.teams?.length ?? 0) > 0;
return (
<PageWrapper
data={hasData ? viewData : null}
isLoading={false}
error={null}
retry={async () => redirect('/leaderboards')}
Template={LeaderboardsPageWrapper}
loading={{ variant: 'full-screen', message: 'Loading leaderboards...' }}
errorConfig={{ variant: 'full-screen' }}
empty={{
icon: Trophy,
title: 'No leaderboard data',
description: 'There is no leaderboard data available at the moment.',
}}
/>
);
if (result.isErr()) {
const error = result.getError();
// Handle different error types
if (error === 'notFound') {
notFound();
} else if (error === 'redirect') {
redirect(routes.public.home);
} else {
// serverError, networkError, unknown, validationError, unauthorized
console.error('Leaderboards error:', error);
notFound();
}
}
// Success
const viewData = result.unwrap();
return <LeaderboardsPageWrapper data={viewData} />;
}