'use client'; import { useState, useEffect, useCallback } from 'react'; import Link from 'next/link'; import { Driver } from '@gridpilot/racing/domain/entities/Driver'; import { getDriverRepository, getDriverStats } from '@/lib/di-container'; import { getLeagueMembers, getCurrentDriverId, type LeagueMembership, type MembershipRole, } from '@/lib/racingLegacyFacade'; interface LeagueMembersProps { leagueId: string; onRemoveMember?: (driverId: string) => void; onUpdateRole?: (driverId: string, role: MembershipRole) => void; showActions?: boolean; } export default function LeagueMembers({ leagueId, onRemoveMember, onUpdateRole, showActions = false }: LeagueMembersProps) { const [members, setMembers] = useState([]); const [drivers, setDrivers] = useState([]); const [loading, setLoading] = useState(true); const [sortBy, setSortBy] = useState<'role' | 'name' | 'date' | 'rating' | 'points' | 'wins'>('rating'); const currentDriverId = getCurrentDriverId(); const loadMembers = useCallback(async () => { setLoading(true); try { const membershipData = getLeagueMembers(leagueId); setMembers(membershipData); const driverRepo = getDriverRepository(); const driverData = await Promise.all( membershipData.map(m => driverRepo.findById(m.driverId)) ); setDrivers(driverData.filter((d): d is Driver => d !== null)); } catch (error) { console.error('Failed to load members:', error); } finally { setLoading(false); } }, [leagueId]); useEffect(() => { loadMembers(); }, [loadMembers]); const getDriverName = (driverId: string): string => { const driver = drivers.find(d => d.id === driverId); return driver?.name || 'Unknown Driver'; }; const getRoleOrder = (role: MembershipRole): number => { const order = { owner: 0, admin: 1, steward: 2, member: 3 }; return order[role]; }; const sortedMembers = [...members].sort((a, b) => { switch (sortBy) { case 'role': return getRoleOrder(a.role) - getRoleOrder(b.role); case 'name': return getDriverName(a.driverId).localeCompare(getDriverName(b.driverId)); case 'date': return new Date(b.joinedAt).getTime() - new Date(a.joinedAt).getTime(); case 'rating': { const statsA = getDriverStats(a.driverId); const statsB = getDriverStats(b.driverId); return (statsB?.rating || 0) - (statsA?.rating || 0); } case 'points': return 0; case 'wins': { const statsA = getDriverStats(a.driverId); const statsB = getDriverStats(b.driverId); return (statsB?.wins || 0) - (statsA?.wins || 0); } default: return 0; } }); const getRoleBadgeColor = (role: MembershipRole): string => { switch (role) { case 'owner': return 'bg-yellow-500/10 text-yellow-500 border-yellow-500/30'; case 'admin': return 'bg-purple-500/10 text-purple-400 border-purple-500/30'; case 'steward': return 'bg-blue-500/10 text-blue-400 border-blue-500/30'; case 'member': return 'bg-primary-blue/10 text-primary-blue border-primary-blue/30'; } }; if (loading) { return (
Loading members...
); } if (members.length === 0) { return (
No members found
); } return (
{/* Sort Controls */}

{members.length} {members.length === 1 ? 'member' : 'members'}

{/* Members Table */}
{showActions && } {sortedMembers.map((member, index) => { const isCurrentUser = member.driverId === currentDriverId; const cannotModify = member.role === 'owner'; const driverStats = getDriverStats(member.driverId); const isTopPerformer = index < 3 && sortBy === 'rating'; return ( {showActions && ( )} ); })}
Driver Rating Rank Wins Role JoinedActions
{getDriverName(member.driverId)} {isCurrentUser && ( (You) )} {isTopPerformer && ( )}
{driverStats?.rating || '—'} #{driverStats?.overallRank || '—'} {driverStats?.wins || 0} {member.role.charAt(0).toUpperCase() + member.role.slice(1)} {new Date(member.joinedAt).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', })} {!cannotModify && !isCurrentUser && (
{onUpdateRole && ( )} {onRemoveMember && ( )}
)} {cannotModify && ( )}
); }