'use client'; import { useState, useEffect } from 'react'; import Card from '@/components/ui/Card'; import DriverIdentity from '@/components/drivers/DriverIdentity'; import { getDriverRepository, getDriverStats } from '@/lib/di-container'; import { EntityMappers } from '@gridpilot/racing/application/mappers/EntityMappers'; import type { DriverDTO } from '@gridpilot/racing/application/dto/DriverDTO'; import type { TeamMembership, TeamRole } from '@gridpilot/racing'; interface TeamRosterProps { teamId: string; memberships: TeamMembership[]; isAdmin: boolean; onRemoveMember?: (driverId: string) => void; onChangeRole?: (driverId: string, newRole: TeamRole) => void; } export default function TeamRoster({ teamId, memberships, isAdmin, onRemoveMember, onChangeRole, }: TeamRosterProps) { const [drivers, setDrivers] = useState>({}); const [loading, setLoading] = useState(true); const [sortBy, setSortBy] = useState<'role' | 'rating' | 'name'>('rating'); useEffect(() => { const loadDrivers = async () => { const driverRepo = getDriverRepository(); const allDrivers = await driverRepo.findAll(); const driverMap: Record = {}; for (const membership of memberships) { const driver = allDrivers.find((d) => d.id === membership.driverId); if (driver) { const dto = EntityMappers.toDriverDTO(driver); if (dto) { driverMap[membership.driverId] = dto; } } } setDrivers(driverMap); setLoading(false); }; void loadDrivers(); }, [memberships]); const getRoleBadgeColor = (role: TeamRole) => { switch (role) { case 'owner': return 'bg-warning-amber/20 text-warning-amber'; case 'manager': return 'bg-primary-blue/20 text-primary-blue'; default: return 'bg-charcoal-outline text-gray-300'; } }; const getRoleLabel = (role: TeamRole) => { return role.charAt(0).toUpperCase() + role.slice(1); }; const sortedMemberships = [...memberships].sort((a, b) => { switch (sortBy) { case 'rating': { const statsA = getDriverStats(a.driverId); const statsB = getDriverStats(b.driverId); return (statsB?.rating || 0) - (statsA?.rating || 0); } case 'role': { const roleOrder = { owner: 0, manager: 1, driver: 2 }; return roleOrder[a.role] - roleOrder[b.role]; } case 'name': { const driverA = drivers[a.driverId]; const driverB = drivers[b.driverId]; return (driverA?.name || '').localeCompare(driverB?.name || ''); } default: return 0; } }); const teamAverageRating = memberships.length > 0 ? Math.round( memberships.reduce((sum, m) => { const stats = getDriverStats(m.driverId); return sum + (stats?.rating || 0); }, 0) / memberships.length, ) : 0; if (loading) { return (
Loading roster...
); } return (

Team Roster

{memberships.length} {memberships.length === 1 ? 'member' : 'members'} • Avg Rating:{' '} {teamAverageRating}

{sortedMemberships.map((membership) => { const driver = drivers[membership.driverId]; const driverStats = getDriverStats(membership.driverId); if (!driver) return null; const canManageMembership = isAdmin && membership.role !== 'owner'; return (
{driver.country} • Joined{' '} {new Date(membership.joinedAt).toLocaleDateString()} } size="md" /> {driverStats && (
{driverStats.rating}
Rating
#{driverStats.overallRank}
Rank
)} {canManageMembership && (
)}
); })}
{memberships.length === 0 && (
No team members yet.
)}
); }