105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import { useParams } from 'next/navigation';
|
|
import Card from '@/components/ui/Card';
|
|
import Button from '@/components/ui/Button';
|
|
import { LeagueSponsorshipsSection } from '@/components/leagues/LeagueSponsorshipsSection';
|
|
import {
|
|
getLeagueRepository,
|
|
getLeagueMembershipRepository,
|
|
} from '@/lib/di-container';
|
|
import { useEffectiveDriverId } from '@/lib/currentDriver';
|
|
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
|
|
import { AlertTriangle, Building, DollarSign } from 'lucide-react';
|
|
import type { League } from '@gridpilot/racing/domain/entities/League';
|
|
|
|
export default function LeagueSponsorshipsPage() {
|
|
const params = useParams();
|
|
const leagueId = params.id as string;
|
|
const currentDriverId = useEffectiveDriverId();
|
|
|
|
const [league, setLeague] = useState<League | null>(null);
|
|
const [isAdmin, setIsAdmin] = useState(false);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
async function loadData() {
|
|
try {
|
|
const leagueRepo = getLeagueRepository();
|
|
const membershipRepo = getLeagueMembershipRepository();
|
|
|
|
const [leagueData, membership] = await Promise.all([
|
|
leagueRepo.findById(leagueId),
|
|
membershipRepo.getMembership(leagueId, currentDriverId),
|
|
]);
|
|
|
|
setLeague(leagueData);
|
|
setIsAdmin(membership ? isLeagueAdminOrHigherRole(membership.role) : false);
|
|
} catch (err) {
|
|
console.error('Failed to load league:', err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
loadData();
|
|
}, [leagueId, currentDriverId]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<Card>
|
|
<div className="py-6 text-sm text-gray-400 text-center">Loading sponsorships...</div>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
if (!isAdmin) {
|
|
return (
|
|
<Card>
|
|
<div className="text-center py-12">
|
|
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-iron-gray/50 flex items-center justify-center">
|
|
<AlertTriangle className="w-8 h-8 text-warning-amber" />
|
|
</div>
|
|
<h3 className="text-lg font-medium text-white mb-2">Admin Access Required</h3>
|
|
<p className="text-sm text-gray-400">
|
|
Only league admins can manage sponsorships.
|
|
</p>
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
if (!league) {
|
|
return (
|
|
<Card>
|
|
<div className="py-6 text-sm text-gray-500 text-center">
|
|
League not found.
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
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>
|
|
|
|
{/* Sponsorships Section */}
|
|
<Card>
|
|
<LeagueSponsorshipsSection
|
|
leagueId={leagueId}
|
|
readOnly={false}
|
|
/>
|
|
</Card>
|
|
</div>
|
|
);
|
|
} |