'use client';
import DriverIdentity from '@/components/drivers/DriverIdentity';
import JoinLeagueButton from '@/components/leagues/JoinLeagueButton';
import LeagueActivityFeed from '@/components/leagues/LeagueActivityFeed';
import SponsorInsightsCard, {
MetricBuilders,
SlotTemplates,
type SponsorMetric,
} from '@/components/sponsors/SponsorInsightsCard';
import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card';
import { LeagueRoleDisplay } from '@/lib/display-objects/LeagueRoleDisplay';
import type { LeagueDetailPageViewModel, DriverSummary } from '@/lib/view-models/LeagueDetailPageViewModel';
import type { RaceViewModel } from '@/lib/view-models/RaceViewModel';
import { Calendar, ExternalLink, Star, Trophy, Users } from 'lucide-react';
import { ReactNode } from 'react';
// ============================================================================
// TYPES
// ============================================================================
interface LeagueDetailTemplateProps {
viewModel: LeagueDetailPageViewModel;
leagueId: string;
isSponsor: boolean;
membership: { role: string } | null;
currentDriverId: string | null;
onMembershipChange: () => void;
onEndRaceModalOpen: (raceId: string) => void;
onLiveRaceClick: (raceId: string) => void;
onBackToLeagues: () => void;
children?: ReactNode;
}
interface LiveRaceCardProps {
races: RaceViewModel[];
membership: { role: string } | null;
onLiveRaceClick: (raceId: string) => void;
onEndRaceModalOpen: (raceId: string) => void;
}
interface LeagueInfoCardProps {
viewModel: LeagueDetailPageViewModel;
}
interface SponsorsSectionProps {
sponsors: Array<{
id: string;
name: string;
tier: 'main' | 'secondary';
logoUrl?: string;
tagline?: string;
websiteUrl?: string;
}>;
}
interface ManagementSectionProps {
ownerSummary?: DriverSummary | null;
adminSummaries: DriverSummary[];
stewardSummaries: DriverSummary[];
leagueId: string;
}
// ============================================================================
// LIVE RACE CARD COMPONENT
// ============================================================================
function LiveRaceCard({ races, membership, onLiveRaceClick, onEndRaceModalOpen }: LiveRaceCardProps) {
if (races.length === 0) return null;
return (
{races.map((race) => (
{membership?.role === 'admin' && (
)}
Started {new Date(race.date).toLocaleDateString()}
{race.registeredCount && (
{race.registeredCount} drivers registered
)}
{race.strengthOfField && (
SOF: {race.strengthOfField}
)}
))}
);
}
// ============================================================================
// LEAGUE INFO CARD COMPONENT
// ============================================================================
function LeagueInfoCard({ viewModel }: LeagueInfoCardProps) {
return (
About
{/* Stats Grid */}
{viewModel.memberships.length}
Members
{viewModel.completedRacesCount}
Races
{viewModel.averageSOF ?? '—'}
Avg SOF
{/* Details */}
Structure
Solo • {viewModel.settings.maxDrivers ?? 32} max
Scoring
{viewModel.scoringConfig?.scoringPresetName ?? 'Standard'}
Created
{new Date(viewModel.createdAt).toLocaleDateString('en-US', {
month: 'short',
year: 'numeric'
})}
{viewModel.socialLinks && (
{viewModel.socialLinks.discordUrl && (
Discord
)}
{viewModel.socialLinks.youtubeUrl && (
YouTube
)}
{viewModel.socialLinks.websiteUrl && (
Website
)}
)}
);
}
// ============================================================================
// SPONSORS SECTION COMPONENT
// ============================================================================
function SponsorsSection({ sponsors }: SponsorsSectionProps) {
if (sponsors.length === 0) return null;
return (
{sponsors.find(s => s.tier === 'main') ? 'Presented by' : 'Sponsors'}
{/* Main Sponsor - Featured prominently */}
{sponsors.filter(s => s.tier === 'main').map(sponsor => (
{sponsor.logoUrl ? (
) : (
)}
{sponsor.name}
Main
{sponsor.tagline && (
{sponsor.tagline}
)}
{sponsor.websiteUrl && (
)}
))}
{/* Secondary Sponsors - Smaller display */}
{sponsors.filter(s => s.tier === 'secondary').length > 0 && (
{sponsors.filter(s => s.tier === 'secondary').map(sponsor => (
{sponsor.logoUrl ? (
) : (
)}
{sponsor.name}
{sponsor.websiteUrl && (
)}
))}
)}
);
}
// ============================================================================
// MANAGEMENT SECTION COMPONENT
// ============================================================================
function ManagementSection({ ownerSummary, adminSummaries, stewardSummaries, leagueId }: ManagementSectionProps) {
if (!ownerSummary && adminSummaries.length === 0 && stewardSummaries.length === 0) return null;
return (
Management
{ownerSummary && (() => {
const summary = ownerSummary;
const roleDisplay = LeagueRoleDisplay.getLeagueRoleDisplay('owner');
const meta = summary.rating !== null
? `Rating ${summary.rating}${summary.rank ? ` • Rank ${summary.rank}` : ''}`
: null;
return (
);
})()}
{adminSummaries.map((summary) => {
const roleDisplay = LeagueRoleDisplay.getLeagueRoleDisplay('admin');
const meta = summary.rating !== null
? `Rating ${summary.rating}${summary.rank ? ` • Rank ${summary.rank}` : ''}`
: null;
return (
);
})}
{stewardSummaries.map((summary) => {
const roleDisplay = LeagueRoleDisplay.getLeagueRoleDisplay('steward');
const meta = summary.rating !== null
? `Rating ${summary.rating}${summary.rank ? ` • Rank ${summary.rank}` : ''}`
: null;
return (
);
})}
);
}
// ============================================================================
// MAIN TEMPLATE COMPONENT
// ============================================================================
export function LeagueDetailTemplate({
viewModel,
leagueId,
isSponsor,
membership,
currentDriverId,
onMembershipChange,
onEndRaceModalOpen,
onLiveRaceClick,
onBackToLeagues,
children,
}: LeagueDetailTemplateProps) {
// Build metrics for SponsorInsightsCard
const leagueMetrics: SponsorMetric[] = [
MetricBuilders.views(viewModel.sponsorInsights.avgViewsPerRace, 'Avg Views/Race'),
MetricBuilders.engagement(viewModel.sponsorInsights.engagementRate),
MetricBuilders.reach(viewModel.sponsorInsights.estimatedReach),
MetricBuilders.sof(viewModel.averageSOF ?? '—'),
];
return (
<>
{/* Sponsor Insights Card - Only shown to sponsors, at top of page */}
{isSponsor && viewModel && (
)}
{/* Live Race Card - Prominently show running races */}
{viewModel && viewModel.runningRaces.length > 0 && (
)}
{/* Action Card */}
{!membership && !isSponsor && (
Join This League
Become a member to participate in races and track your progress
)}
{/* League Overview - Activity Center with Info Sidebar */}
{/* Center - Activity Feed */}
Recent Activity
{/* Right Sidebar - League Info */}
{/* League Info - Combined */}
{/* Sponsors Section - Show sponsor logos */}
{viewModel.sponsors.length > 0 && (
)}
{/* Management */}
{/* Children (for modals, etc.) */}
{children}
>
);
}