import { Form, Link } from "react-router"; import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId"; import { loader, action } from "./admin.sports-seasons.$id.events.$eventId.server"; import { Button } from "~/components/ui/button"; import { Input } from "~/components/ui/input"; import { Label } from "~/components/ui/label"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "~/components/ui/select"; import { Badge } from "~/components/ui/badge"; import { ArrowLeft, Trophy, CheckCircle2, Pencil, Trash2, Brackets, Save } from "lucide-react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "~/components/ui/table"; import { useState } from "react"; export { loader, action }; export default function EventResults({ loaderData, actionData, }: Route.ComponentProps) { const { sportsSeason, event, participants, results, participantResults, seasonResults, qpConfig, qpStandings } = loaderData; const [hasChanges, setHasChanges] = useState(false); // Create a map of participants with results for easy lookup const participantResultsMap = new Map( results.map((r: { participant: { id: string } }) => [r.participant.id, r]) ); // Get participants without results const participantsWithoutResults = participants.filter( (p: { id: string }) => !participantResultsMap.has(p.id) ); // Sort results by placement const sortedResults = [...results].sort((a, b) => (a.placement || 999) - (b.placement || 999)); // Create a map of season results for easy lookup const seasonResultsMap = seasonResults ? new Map( seasonResults.map((r: { participantId: string }) => [r.participantId, r]) ) : new Map(); const getEventTypeLabel = (type: string) => { switch (type) { case "playoff_game": return "Bracket"; case "major_tournament": return "Major Tournament"; case "final_standings": return "Final Standings"; default: return type; } }; return (

{event.name}

{sportsSeason.sport.name} - {sportsSeason.name} •{" "} {getEventTypeLabel(event.eventType)} {event.playoffRound && ` • ${event.playoffRound}`}

{event.eventType === "playoff_game" && ( )} {event.isComplete ? ( Completed ) : ( In Progress )} {event.isQualifyingEvent && ( Qualifying Event )}
{/* Debug info and manual QP processing for completed major tournaments */} {event.isComplete && event.eventType === "major_tournament" && ( Event Processing Status
Event Type: {event.eventType}
Is Qualifying Event: {event.isQualifyingEvent ? 'Yes' : 'No'}
Sports Season Pattern: {sportsSeason.scoringPattern || 'not set'}
Results Count: {results.length}
{!event.isQualifyingEvent && (

This event needs to be marked as a qualifying event to award qualifying points.

)} {event.isQualifyingEvent && (
)}
)} {actionData?.error && (
{actionData.error}
)} {actionData?.success && (
{actionData.success}
)} {/* Season Standings Table for final_standings events */} {event.eventType === "final_standings" && !event.isComplete && ( <> Season Standings Tracker Enter championship points for each participant. Positions are automatically calculated based on points (highest = 1st). When the season ends, mark this event as complete to assign fantasy points to the top 8.
Participant Championship Points {participants.map((participant: { id: string; name: string }) => { const result = seasonResultsMap.get(participant.id); const currentPoints = result?.currentPoints || ""; return ( {participant.name} setHasChanges(true)} /> ); })}

{hasChanges ? "You have unsaved changes" : "Update standings after each race/event during the season"}

{/* Complete Season Button */} Finalize Season When the season is complete, mark this event as complete to:
  • Convert the top 8 participants (by position) to fantasy placements 1-8
  • Award fantasy points based on league scoring rules
  • Update all league standings

⚠️ Make sure all standings are saved before completing

)} {/* Regular Result Entry for other event types */} {event.eventType !== "final_standings" && !event.isComplete && ( Add Result Enter the placement for a participant in this event
)} {/* Manual QP Processing Button (for existing events) */} {event.isComplete && event.eventType === "major_tournament" && sportsSeason.scoringPattern === "qualifying_points" && results.length > 0 && ( Process Qualifying Points This event is complete but qualifying points haven't been awarded yet. Click below to award QP based on the results entered.
)} {/* Current Results - Hide for playoff events since they use the bracket */} {event.eventType !== "playoff_game" && (
Results {results.length} of {participants.length} participants have results
{!event.isComplete && results.length > 0 && event.eventType !== "final_standings" && (
)}
{sortedResults.length === 0 ? (

No results added yet. Add results using the form above.

) : ( Placement Participant {event.isQualifyingEvent && event.isComplete && ( QP Awarded )} {!event.isComplete && Actions} {sortedResults.map((result) => (
{result.placement === 1 && ( 🥇 )} {result.placement === 2 && ( 🥈 )} {result.placement === 3 && ( 🥉 )} {result.placement}
{result.participant.name} {event.isQualifyingEvent && event.isComplete && ( {result.qualifyingPointsAwarded ? ( {parseFloat(result.qualifyingPointsAwarded).toFixed(2)} QP ) : ( 0 QP )} )} {!event.isComplete && (
{ if (e.key === 'Enter') { e.currentTarget.form?.requestSubmit(); } }} />
)}
))}
)}
)} {/* Bracket Explanation Card for Playoff Events */} {event.eventType === "playoff_game" && !participantResults?.length && ( Bracket Event This is a bracket/playoff event. Results are managed through the bracket interface.

To complete this event:

  1. Click "Manage Bracket" above to set match winners
  2. Once all matches are complete, click "Finalize Bracket"
  3. Fantasy placements and points will appear below automatically
)} {/* Participant Results with Fantasy Points */} {participantResults && participantResults.length > 0 && (
{event.eventType === "playoff_game" ? ( <> Fantasy Points Awarded (from Bracket) ) : ( "Fantasy Points Awarded" )} {event.eventType === "playoff_game" ? `${participantResults.length} participants assigned placements from bracket results` : "Points calculated from bracket placements (sorted by position)" }
{event.eventType === "playoff_game" && event.isComplete && ( Bracket Finalized )}
Final Position Participant Fantasy Points {[...participantResults] .sort((a: any, b: any) => { const posA = a.finalPosition ?? 999; const posB = b.finalPosition ?? 999; return posA - posB; }) .map((result: any) => (
{result.finalPosition === 1 && ( 🥇 )} {result.finalPosition === 2 && ( 🥈 )} {result.finalPosition === 3 && ( 🥉 )} {result.finalPosition === 0 ? ( Early Elimination ) : ( `${result.finalPosition}${ result.finalPosition === 1 ? "st" : result.finalPosition === 2 ? "nd" : result.finalPosition === 3 ? "rd" : "th" }` )}
{result.participant.name} {result.qualifyingPoints ? ( {parseFloat(result.qualifyingPoints).toFixed(2)} pts ) : ( - )}
))}
)}
); }