Files
gridpilot.gg/apps/website/components/teams/SkillLevelSection.tsx
2025-12-30 18:33:15 +01:00

108 lines
3.9 KiB
TypeScript

import { useState } from 'react';
import { ChevronRight, Users, Trophy, UserPlus } from 'lucide-react';
import type { TeamSummaryViewModel } from '@/lib/view-models/TeamSummaryViewModel';
import TeamCard from './TeamCard';
type SkillLevel = 'pro' | 'advanced' | 'intermediate' | 'beginner';
type TeamSpecialization = 'endurance' | 'sprint' | 'mixed';
interface SkillLevelConfig {
id: SkillLevel;
label: string;
icon: React.ElementType;
color: string;
bgColor: string;
borderColor: string;
description: string;
}
interface SkillLevelSectionProps {
level: SkillLevelConfig;
teams: TeamSummaryViewModel[];
onTeamClick: (id: string) => void;
defaultExpanded?: boolean;
}
export default function SkillLevelSection({
level,
teams,
onTeamClick,
defaultExpanded = false
}: SkillLevelSectionProps) {
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
const recruitingTeams = teams.filter((t) => t.isRecruiting);
const displayedTeams = isExpanded ? teams : teams.slice(0, 3);
const Icon = level.icon;
if (teams.length === 0) return null;
const specialization = (teamSpecialization: string | undefined): TeamSpecialization | undefined => {
if (teamSpecialization === 'endurance' || teamSpecialization === 'sprint' || teamSpecialization === 'mixed') {
return teamSpecialization;
}
return undefined;
};
return (
<div className="mb-8">
{/* Section Header */}
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-3">
<div className={`flex h-11 w-11 items-center justify-center rounded-xl ${level.bgColor} border ${level.borderColor}`}>
<Icon className={`w-5 h-5 ${level.color}`} />
</div>
<div>
<div className="flex items-center gap-2">
<h2 className="text-xl font-bold text-white">{level.label}</h2>
<span className="px-2 py-0.5 rounded-full text-xs bg-charcoal-outline/50 text-gray-400">
{teams.length} {teams.length === 1 ? 'team' : 'teams'}
</span>
{recruitingTeams.length > 0 && (
<span className="flex items-center gap-1 px-2 py-0.5 rounded-full text-xs bg-performance-green/10 text-performance-green border border-performance-green/20">
<UserPlus className="w-3 h-3" />
{recruitingTeams.length} recruiting
</span>
)}
</div>
<p className="text-sm text-gray-500">{level.description}</p>
</div>
</div>
{teams.length > 3 && (
<button
type="button"
onClick={() => setIsExpanded(!isExpanded)}
className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm text-gray-400 hover:text-white hover:bg-iron-gray/50 transition-all"
>
{isExpanded ? 'Show less' : `View all ${teams.length}`}
<ChevronRight className={`w-4 h-4 transition-transform ${isExpanded ? 'rotate-90' : ''}`} />
</button>
)}
</div>
{/* Teams Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{displayedTeams.map((team) => (
<TeamCard
key={team.id}
id={team.id}
name={team.name}
description={team.description ?? ''}
logo={team.logoUrl}
memberCount={team.memberCount}
rating={team.rating}
totalWins={team.totalWins}
totalRaces={team.totalRaces}
performanceLevel={team.performanceLevel as SkillLevel}
isRecruiting={team.isRecruiting}
specialization={specialization(team.specialization)}
region={team.region ?? ''}
languages={team.languages}
category={team.category}
onClick={() => onTeamClick(team.id)}
/>
))}
</div>
</div>
);
}