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 } = 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 (
Back to Events
{event.name}
{sportsSeason.sport.name} - {sportsSeason.name} •{" "}
{getEventTypeLabel(event.eventType)}
{event.playoffRound && ` • ${event.playoffRound}`}
{event.eventType === "playoff_game" && (
Manage Bracket
)}
{event.isComplete ? (
Completed
) : (
In Progress
)}
{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.
{/* 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
)}
{/* Current Results */}
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.isComplete && Actions }
{sortedResults.map((result) => (
{result.placement === 1 && (
🥇
)}
{result.placement === 2 && (
🥈
)}
{result.placement === 3 && (
🥉
)}
{result.placement}
{result.participant.name}
{!event.isComplete && (
)}
))}
)}
{/* Participant Results with Fantasy Points */}
{participantResults && participantResults.length > 0 && (
Fantasy Points Awarded
Points calculated from bracket placements (sorted by position)
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(0)} pts
) : (
-
)}
))}
)}
);
}