'use client'; import { useState, useEffect, useMemo } from 'react'; import { useParams, useRouter } from 'next/navigation'; import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; import { getLeagueRepository, getDriverRepository, getGetLeagueFullConfigUseCase, getLeagueMembershipRepository, getDriverStats, getAllDriverRankings, getListLeagueScoringPresetsUseCase, getTransferLeagueOwnershipUseCase } from '@/lib/di-container'; import { LeagueFullConfigPresenter } from '@/lib/presenters/LeagueFullConfigPresenter'; import { LeagueScoringPresetsPresenter } from '@/lib/presenters/LeagueScoringPresetsPresenter'; import { useEffectiveDriverId } from '@/lib/currentDriver'; import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles'; import { ScoringPatternSection, ChampionshipsSection } from '@/components/leagues/LeagueScoringSection'; import { LeagueDropSection } from '@/components/leagues/LeagueDropSection'; import { ReadonlyLeagueInfo } from '@/components/leagues/ReadonlyLeagueInfo'; import type { LeagueConfigFormModel } from '@gridpilot/racing/application'; import type { League } from '@gridpilot/racing/domain/entities/League'; import type { DriverDTO } from '@gridpilot/racing/application/dto/DriverDTO'; import type { LeagueScoringPresetDTO } from '@gridpilot/racing/application/ports/LeagueScoringPresetProvider'; import { EntityMappers } from '@gridpilot/racing/application/mappers/EntityMappers'; import DriverSummaryPill from '@/components/profile/DriverSummaryPill'; import { AlertTriangle, Settings, Trophy, Calendar, TrendingDown, Edit, Users, UserCog } from 'lucide-react'; export default function LeagueSettingsPage() { const params = useParams(); const leagueId = params.id as string; const currentDriverId = useEffectiveDriverId(); const [league, setLeague] = useState(null); const [configForm, setConfigForm] = useState(null); const [presets, setPresets] = useState([]); const [ownerDriver, setOwnerDriver] = useState(null); const [loading, setLoading] = useState(true); const [isAdmin, setIsAdmin] = useState(false); const [showTransferDialog, setShowTransferDialog] = useState(false); const [selectedNewOwner, setSelectedNewOwner] = useState(''); const [transferring, setTransferring] = useState(false); const [allMembers, setAllMembers] = useState([]); const router = useRouter(); useEffect(() => { async function checkAdmin() { const membershipRepo = getLeagueMembershipRepository(); const membership = await membershipRepo.getMembership(leagueId, currentDriverId); setIsAdmin(membership ? isLeagueAdminOrHigherRole(membership.role) : false); } checkAdmin(); }, [leagueId, currentDriverId]); useEffect(() => { async function loadSettings() { setLoading(true); try { const leagueRepo = getLeagueRepository(); const driverRepo = getDriverRepository(); const useCase = getGetLeagueFullConfigUseCase(); const presetsUseCase = getListLeagueScoringPresetsUseCase(); const leagueData = await leagueRepo.findById(leagueId); if (!leagueData) { setLoading(false); return; } setLeague(leagueData); const configPresenter = new LeagueFullConfigPresenter(); await useCase.execute({ leagueId }, configPresenter); const configViewModel = configPresenter.getViewModel(); if (configViewModel) { setConfigForm(configViewModel as LeagueConfigFormModel); } const presetsPresenter = new LeagueScoringPresetsPresenter(); await presetsUseCase.execute(undefined as void, presetsPresenter); const presetsViewModel = presetsPresenter.getViewModel(); setPresets(presetsViewModel.presets); const entity = await driverRepo.findById(leagueData.ownerId); if (entity) { setOwnerDriver(EntityMappers.toDriverDTO(entity)); } const membershipRepo = getLeagueMembershipRepository(); const memberships = await membershipRepo.getLeagueMembers(leagueId); const memberDrivers: DriverDTO[] = []; for (const m of memberships) { if (m.driverId !== leagueData.ownerId && m.status === 'active') { const d = await driverRepo.findById(m.driverId); if (d) { const dto = EntityMappers.toDriverDTO(d); if (dto) { memberDrivers.push(dto); } } } } setAllMembers(memberDrivers); } catch (err) { console.error('Failed to load league settings:', err); } finally { setLoading(false); } } if (isAdmin) { loadSettings(); } }, [leagueId, isAdmin]); const ownerSummary = useMemo(() => { if (!ownerDriver) { return null; } const stats = getDriverStats(ownerDriver.id); const allRankings = getAllDriverRankings(); let rating: number | null = stats?.rating ?? null; let rank: number | null = null; if (stats) { if (typeof stats.overallRank === 'number' && stats.overallRank > 0) { rank = stats.overallRank; } else { const indexInGlobal = allRankings.findIndex( (stat) => stat.driverId === stats.driverId, ); if (indexInGlobal !== -1) { rank = indexInGlobal + 1; } } if (rating === null) { const globalEntry = allRankings.find( (stat) => stat.driverId === stats.driverId, ); if (globalEntry) { rating = globalEntry.rating; } } } return { driver: ownerDriver, rating, rank, }; }, [ownerDriver]); const handleTransferOwnership = async () => { if (!selectedNewOwner || !league) return; setTransferring(true); try { const useCase = getTransferLeagueOwnershipUseCase(); await useCase.execute({ leagueId, currentOwnerId: currentDriverId, newOwnerId: selectedNewOwner, }); setShowTransferDialog(false); router.refresh(); } catch (err) { console.error('Failed to transfer ownership:', err); alert(err instanceof Error ? err.message : 'Failed to transfer ownership'); } finally { setTransferring(false); } }; if (!isAdmin) { return (

Admin Access Required

Only league admins can access settings.

); } if (loading) { return (
Loading configuration…
); } if (!configForm || !league) { return (
Unable to load league configuration for this demo league.
); } return (
{/* Header */}

League Settings

Manage your league configuration

{/* READONLY INFORMATION SECTION - Compact */}
{/* League Owner - Compact */}

League Owner

{ownerSummary ? ( ) : (

Loading owner details...

)}
{/* Transfer Ownership - Owner Only */} {league.ownerId === currentDriverId && allMembers.length > 0 && (

Transfer Ownership

Transfer league ownership to another active member. You will become an admin.

{!showTransferDialog ? ( ) : (
)}
)}
); }