website refactor

This commit is contained in:
2026-01-14 13:39:24 +01:00
parent faa4c3309e
commit 8b67295442
28 changed files with 1082 additions and 851 deletions

View File

@@ -1,79 +1,37 @@
'use client';
import { LeagueSponsorshipsPageQuery } from '@/lib/page-queries/page-queries/LeagueSponsorshipsPageQuery';
import { LeagueSponsorshipsTemplate } from '@/templates/LeagueSponsorshipsTemplate';
import { notFound } from 'next/navigation';
import { LeagueSponsorshipsSection } from '@/components/leagues/LeagueSponsorshipsSection';
import { StatefulPageWrapper } from '@/components/shared/state/StatefulPageWrapper';
import { useEffectiveDriverId } from "@/lib/hooks/useEffectiveDriverId";
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
import { useLeagueSponsorshipsPageData } from "@/lib/hooks/league/useLeagueSponsorshipsPageData";
import { ApiError } from '@/lib/api/base/ApiError';
import { Building } from 'lucide-react';
import { useParams } from 'next/navigation';
interface SponsorshipsData {
league: any;
isAdmin: boolean;
interface Props {
params: { id: string };
}
function SponsorshipsTemplate({ data }: { data: SponsorshipsData }) {
return (
<div className="space-y-6">
{/* Header */}
<div className="flex items-center gap-3">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary-blue/10">
<Building className="w-6 h-6 text-primary-blue" />
</div>
<div>
<h1 className="text-2xl font-bold text-white">Sponsorships</h1>
<p className="text-sm text-gray-400">Manage sponsorship slots and review requests</p>
</div>
</div>
export default async function LeagueSponsorshipsPage({ params }: Props) {
const leagueId = params.id;
{/* Sponsorships Section */}
<LeagueSponsorshipsSection
leagueId={data.league.id}
readOnly={false}
/>
</div>
);
}
if (!leagueId) {
notFound();
}
export default function LeagueSponsorshipsPage() {
const params = useParams();
const leagueId = params.id as string;
const currentDriverId = useEffectiveDriverId() || '';
const result = await LeagueSponsorshipsPageQuery.execute(leagueId);
// Fetch data using domain hook
const { data, isLoading, error, refetch } = useLeagueSponsorshipsPageData(leagueId, currentDriverId);
if (result.isErr()) {
const error = result.getError();
if (error.type === 'notFound') {
notFound();
}
// For serverError, show the template with empty data
return <LeagueSponsorshipsTemplate viewData={{
leagueId,
league: {
id: leagueId,
name: 'Unknown League',
description: 'League information unavailable',
},
sponsorshipSlots: [],
sponsorshipRequests: [],
}} />;
}
// Transform data for the template
const transformedData: SponsorshipsData | undefined = data?.league && data.membership !== null
? {
league: data.league,
isAdmin: LeagueRoleUtility.isLeagueAdminOrHigherRole(data.membership?.role || 'member'),
}
: undefined;
// Check if user is not admin to show appropriate state
const isNotAdmin = transformedData && !transformedData.isAdmin;
return (
<StatefulPageWrapper
data={transformedData}
isLoading={isLoading}
error={error as ApiError | null}
retry={refetch}
Template={SponsorshipsTemplate}
loading={{ variant: 'skeleton', message: 'Loading sponsorships...' }}
errorConfig={{ variant: 'full-screen' }}
empty={isNotAdmin ? {
icon: Building,
title: 'Admin Access Required',
description: 'Only league admins can manage sponsorships.',
} : {
icon: Building,
title: 'League not found',
description: 'The league may have been deleted or is no longer accessible.',
}}
/>
);
return <LeagueSponsorshipsTemplate viewData={result.unwrap()} />;
}