Files
gridpilot.gg/apps/website/app/leaderboards/page.tsx
2026-01-14 02:02:24 +01:00

61 lines
2.2 KiB
TypeScript

import { PageWrapper } from '@/components/shared/state/PageWrapper';
import { Trophy } from 'lucide-react';
import { 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
// ============================================================================
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.',
}}
/>
);
}
}