'use client'; import { FileText, Users, Calendar, Trophy, Award, Rocket, Eye, EyeOff, Gamepad2, User, UsersRound, Clock, Flag, Zap, Timer, TrendingDown, Check, Globe, Medal, } from 'lucide-react'; import type { LeagueConfigFormModel } from '@core/racing/application'; import type { LeagueScoringPresetDTO } from '@core/racing/application/ports/LeagueScoringPresetProvider'; interface LeagueReviewSummaryProps { form: LeagueConfigFormModel; presets: LeagueScoringPresetDTO[]; } // Individual review card component function ReviewCard({ icon: Icon, iconColor = 'text-primary-blue', bgColor = 'bg-primary-blue/10', title, children, }: { icon: React.ElementType; iconColor?: string; bgColor?: string; title: string; children: React.ReactNode; }) { return (

{title}

{children}
); } // Info row component for consistent layout function InfoRow({ icon: Icon, label, value, valueClass = '', }: { icon?: React.ElementType; label: string; value: React.ReactNode; valueClass?: string; }) { return (
{Icon && } {label}
{value}
); } // Badge component for enabled features function FeatureBadge({ icon: Icon, label, enabled, color = 'primary-blue', }: { icon: React.ElementType; label: string; enabled: boolean; color?: string; }) { if (!enabled) return null; return ( {label} ); } export default function LeagueReviewSummary({ form, presets }: LeagueReviewSummaryProps) { const { basics, structure, timings, scoring, championships, dropPolicy, stewarding } = form; const seasonName = (form as LeagueConfigFormModel & { seasonName?: string }).seasonName; const modeLabel = structure.mode === 'solo' ? 'Solo drivers' : 'Team-based'; const modeDescription = structure.mode === 'solo' ? 'Individual competition' : 'Teams with fixed rosters'; const capacityValue = (() => { if (structure.mode === 'solo') { return typeof structure.maxDrivers === 'number' ? structure.maxDrivers : '—'; } return typeof structure.maxTeams === 'number' ? structure.maxTeams : '—'; })(); const capacityLabel = structure.mode === 'solo' ? 'drivers' : 'teams'; const formatMinutes = (value: number | undefined) => { if (typeof value !== 'number' || value <= 0) return '—'; return `${value} min`; }; const getDropRuleInfo = () => { if (dropPolicy.strategy === 'none') { return { emoji: '✓', label: 'All count', description: 'Every race counts' }; } if (dropPolicy.strategy === 'bestNResults') { return { emoji: '🏆', label: `Best ${dropPolicy.n ?? 'N'}`, description: `Only best ${dropPolicy.n ?? 'N'} results count`, }; } if (dropPolicy.strategy === 'dropWorstN') { return { emoji: '🗑️', label: `Drop ${dropPolicy.n ?? 'N'}`, description: `Worst ${dropPolicy.n ?? 'N'} dropped`, }; } return { emoji: '✓', label: 'All count', description: 'Every race counts' }; }; const dropRuleInfo = getDropRuleInfo(); const preset = presets.find((p) => p.id === scoring.patternId) ?? null; const seasonStartLabel = timings.seasonStartDate ? new Date(timings.seasonStartDate).toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric', }) : null; const stewardingLabel = (() => { switch (stewarding.decisionMode) { case 'admin_only': return 'Admin-only decisions'; case 'steward_vote': return 'Steward panel voting'; default: return stewarding.decisionMode; } })(); const getScoringEmoji = () => { if (!preset) return '🏁'; const name = preset.name.toLowerCase(); if (name.includes('sprint') || name.includes('double')) return '⚡'; if (name.includes('endurance') || name.includes('long')) return '🏆'; if (name.includes('club') || name.includes('casual')) return '🏅'; return '🏁'; }; // Normalize visibility to new terminology const isRanked = basics.visibility === 'ranked' || basics.visibility === 'public'; const visibilityLabel = isRanked ? 'Ranked' : 'Unranked'; const visibilityDescription = isRanked ? 'Competitive • Affects ratings' : 'Casual • Friends only'; // Calculate total weekend duration const totalWeekendMinutes = (timings.practiceMinutes ?? 0) + (timings.qualifyingMinutes ?? 0) + (timings.sprintRaceMinutes ?? 0) + (timings.mainRaceMinutes ?? 0); return (
{/* League Summary */}

League summary

{/* Background decoration */}

{basics.name || 'Your New League'}

{basics.description || 'Ready to launch your racing series!'}

{/* Ranked/Unranked Badge */} {isRanked ? : } {visibilityLabel} • {visibilityDescription} iRacing {structure.mode === 'solo' ? : } {modeLabel}
{/* Season Summary */}

First season summary

{seasonName || 'First season of this league'} {seasonStartLabel && ( <> Starts {seasonStartLabel} )} {typeof timings.roundsPlanned === 'number' && ( <> {timings.roundsPlanned} rounds planned )} Stewarding: {stewardingLabel}
{/* Stats Grid */}
{/* Capacity */}
{capacityValue}
{capacityLabel}
{/* Rounds */}
{timings.roundsPlanned ?? '—'}
rounds
{/* Weekend Duration */}
{totalWeekendMinutes > 0 ? `${totalWeekendMinutes}` : '—'}
min/weekend
{/* Championships */}
{[championships.enableDriverChampionship, championships.enableTeamChampionship, championships.enableNationsChampionship, championships.enableTrophyChampionship].filter(Boolean).length}
championships
{/* Detail Cards Grid */}
{/* Schedule Card */}
{timings.practiceMinutes && timings.practiceMinutes > 0 && ( )} {timings.sprintRaceMinutes && timings.sprintRaceMinutes > 0 && ( )}
{/* Scoring Card */}
{/* Scoring Preset */}
{getScoringEmoji()}
{preset?.name ?? 'Custom'}
{preset?.sessionSummary ?? 'Custom scoring enabled'}
{scoring.customScoringEnabled && ( Custom )}
{/* Drop Rule */}
{dropRuleInfo.emoji}
{dropRuleInfo.label}
{dropRuleInfo.description}
{/* Championships Section */}
{championships.enableDriverChampionship && ( Driver Championship )} {championships.enableTeamChampionship && ( Team Championship )} {championships.enableNationsChampionship && ( Nations Cup )} {championships.enableTrophyChampionship && ( Trophy Championship )} {![championships.enableDriverChampionship, championships.enableTeamChampionship, championships.enableNationsChampionship, championships.enableTrophyChampionship].some(Boolean) && ( No championships enabled )}
{/* Ready to launch message */}

Ready to launch!

Click "Create League" to launch your racing series. You can modify all settings later.

); }