'use client'; import { LeagueMemberRow } from '@/components/leagues/LeagueMemberRow'; import { LeagueMemberTable } from '@/components/leagues/LeagueMemberTable'; import { EmptyState } from '@/ui/EmptyState'; import { LoadingWrapper } from '@/ui/LoadingWrapper'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { useInject } from '@/lib/di/hooks/useInject'; import { DRIVER_SERVICE_TOKEN, LEAGUE_MEMBERSHIP_SERVICE_TOKEN } from '@/lib/di/tokens'; import { routes } from '@/lib/routing/RouteConfig'; import type { LeagueMembership } from '@/lib/types/LeagueMembership'; import type { MembershipRole } from '@/lib/types/MembershipRole'; import { DriverViewModel } from '@/lib/view-models/DriverViewModel'; import { Button } from '@/ui/Button'; import { Select } from '@/ui/Select'; import { Text } from '@/ui/Text'; import { Box } from '@/ui/Box'; import { Group } from '@/ui/Group'; import { ControlBar } from '@/ui/ControlBar'; import React, { useCallback, useEffect, useState } from 'react'; interface LeagueMembersProps { leagueId: string; onRemoveMember?: (driverId: string) => void; onUpdateRole?: (driverId: string, role: MembershipRole) => void; showActions?: boolean; } export function LeagueMembers({ leagueId, onRemoveMember, onUpdateRole, showActions = false }: LeagueMembersProps) { const [members, setMembers] = useState([]); const [driversById, setDriversById] = useState>({}); const [loading, setLoading] = useState(true); const [sortBy, setSortBy] = useState<'role' | 'name' | 'date' | 'rating' | 'points' | 'wins'>('rating'); const currentDriverId = useEffectiveDriverId(); const leagueMembershipService = useInject(LEAGUE_MEMBERSHIP_SERVICE_TOKEN); const driverService = useInject(DRIVER_SERVICE_TOKEN); const loadMembers = useCallback(async () => { setLoading(true); try { await leagueMembershipService.fetchLeagueMemberships(leagueId); const membershipData = leagueMembershipService.getLeagueMembers(leagueId); setMembers(membershipData); const uniqueDriverIds = Array.from(new Set(membershipData.map((m: LeagueMembership) => m.driverId))); if (uniqueDriverIds.length > 0) { const result = await driverService.findByIds(uniqueDriverIds); if (result.isOk()) { const driverDtos = result.unwrap(); const byId: Record = {}; for (const dto of driverDtos) { byId[dto.id] = new DriverViewModel({ ...dto, avatarUrl: dto.avatarUrl ?? null }); } setDriversById(byId); } } else { setDriversById({}); } } catch (error) { console.error('Failed to load members:', error); } finally { setLoading(false); } }, [leagueId, leagueMembershipService, driverService]); useEffect(() => { loadMembers(); }, [loadMembers]); const getDriverName = (driverId: string): string => { const driver = driversById[driverId]; return driver?.name || 'Unknown Driver'; }; const getRoleOrder = (role: MembershipRole): number => { const order: Record = { owner: 0, admin: 1, steward: 2, member: 3 }; return order[role]; }; const getDriverStats = (): { rating: number; wins: number; overallRank: number } | null => { return null; }; 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(); const statsB = getDriverStats(); return (statsB?.rating || 0) - (statsA?.rating || 0); } case 'points': return 0; case 'wins': { const statsA = getDriverStats(); const statsB = getDriverStats(); return (statsB?.wins || 0) - (statsA?.wins || 0); } default: return 0; } }); const getRoleVariant = (role: MembershipRole): 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' => { switch (role) { case 'owner': return 'warning'; case 'admin': return 'primary'; case 'steward': return 'info'; case 'member': return 'primary'; default: return 'default'; } }; if (loading) { return ; } if (members.length === 0) { return ( ); } return ( {members.length} {members.length === 1 ? 'member' : 'members'} } > Sort by: ) => onUpdateRole(member.driverId, e.target.value as MembershipRole)} options={[ { value: 'member', label: 'Member' }, { value: 'steward', label: 'Steward' }, { value: 'admin', label: 'Admin' }, ]} fullWidth={false} /> )} {onRemoveMember && ( )} ) : (showActions && cannotModify ? : undefined)} /> ); })} ); }