Files
gridpilot.gg/apps/website/app/leagues/[id]/layout.tsx
Marc Mintel 9ac74f5046
Some checks failed
CI / lint-typecheck (pull_request) Failing after 12s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
code quality
2026-01-26 17:22:01 +01:00

126 lines
4.2 KiB
TypeScript

import { notFound } from 'next/navigation';
import { LeagueDetailPageQuery } from '@/lib/page-queries/LeagueDetailPageQuery';
import { LeagueDetailTemplate } from '@/templates/LeagueDetailTemplate';
import { LeagueDetailViewDataBuilder } from '@/lib/builders/view-data/LeagueDetailViewDataBuilder';
import { DriverService } from '@/lib/services/drivers/DriverService';
import { Text } from '@/ui/Text';
export default async function LeagueLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ id: string }>;
}) {
const { id: leagueId } = await params;
// Execute PageQuery to get league data
const [result, currentDriver] = await Promise.all([
LeagueDetailPageQuery.execute(leagueId),
new DriverService().getCurrentDriver(),
]);
if (result.isErr()) {
const error = result.getError();
if (error === 'notFound' || error === 'redirect') {
notFound();
}
// Return error state
return (
<LeagueDetailTemplate
viewData={{
leagueId,
name: 'Error',
description: 'Failed to load league',
info: { name: 'Error', description: 'Error', membersCount: 0, racesCount: 0, avgSOF: 0, structure: '', scoring: '', createdAt: '' },
runningRaces: [],
sponsors: [],
ownerSummary: null,
adminSummaries: [],
stewardSummaries: [],
memberSummaries: [],
sponsorInsights: null,
league: {
id: leagueId,
name: 'Error',
game: 'Unknown',
tier: 'starter',
season: 'Unknown',
description: 'Error',
drivers: 0,
races: 0,
completedRaces: 0,
totalImpressions: 0,
avgViewsPerRace: 0,
engagement: 0,
rating: 0,
seasonStatus: 'completed',
seasonDates: { start: '', end: '' },
sponsorSlots: {
main: { price: 0, status: 'occupied' },
secondary: { price: 0, total: 0, occupied: 0 }
},
ownerId: '',
createdAt: '',
settings: {},
usedSlots: 0,
} as any,
drivers: [],
races: [],
seasonProgress: { completedRaces: 0, totalRaces: 0, percentage: 0 },
recentResults: [],
walletBalance: 0,
pendingProtestsCount: 0,
pendingJoinRequestsCount: 0
}}
tabs={[]}
>
<Text align="center">Failed to load league</Text>
</LeagueDetailTemplate>
);
}
const data = result.unwrap();
const viewData = LeagueDetailViewDataBuilder.build({
league: data.league,
owner: data.owner,
scoringConfig: data.scoringConfig,
memberships: data.memberships,
races: data.races,
sponsors: data.sponsors,
});
// Define tab configuration
const baseTabs = [
{ label: 'Overview', href: `/leagues/${leagueId}`, exact: true },
{ label: 'Schedule', href: `/leagues/${leagueId}/schedule`, exact: false },
{ label: 'Standings', href: `/leagues/${leagueId}/standings`, exact: false },
{ label: 'Roster', href: `/leagues/${leagueId}/roster`, exact: false },
{ label: 'Rulebook', href: `/leagues/${leagueId}/rulebook`, exact: false },
];
// Check if user is admin or owner
const isOwner = currentDriver && data.league.ownerId === currentDriver.id;
const isAdmin = currentDriver && data.memberships.members?.some((m: any) => m.driverId === currentDriver.id && m.role === 'admin');
const hasAdminAccess = isOwner || isAdmin;
const adminTabs = hasAdminAccess ? [
{ label: 'Schedule Admin', href: `/leagues/${leagueId}/schedule/admin`, exact: false },
{ label: 'Sponsorships', href: `/leagues/${leagueId}/sponsorships`, exact: false },
{ label: 'Stewarding', href: `/leagues/${leagueId}/stewarding`, exact: false },
{ label: 'Wallet', href: `/leagues/${leagueId}/wallet`, exact: false },
{ label: 'Settings', href: `/leagues/${leagueId}/settings`, exact: false },
] : [];
const tabs = [...baseTabs, ...adminTabs];
return (
<LeagueDetailTemplate
viewData={viewData}
tabs={tabs}
>
{children}
</LeagueDetailTemplate>
);
}