import { useState } from "react"; import { Form, Link, redirect } from "react-router"; import { getAuth } from "@clerk/react-router/server"; import { findLeagueById, updateLeague, deleteLeague } from "~/models/league"; import { isCommissioner } from "~/models/commissioner"; import { findCurrentSeason } from "~/models/season"; import { findTeamsBySeasonId } from "~/models/team"; import type { Route } from "./+types/$leagueId.settings"; 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 { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "~/components/ui/alert-dialog"; export async function loader(args: Route.LoaderArgs) { const { userId } = await getAuth(args); const { params } = args; const { leagueId } = params; if (!userId) { throw new Response("Unauthorized", { status: 401 }); } // Fetch league const league = await findLeagueById(leagueId); if (!league) { throw new Response("League not found", { status: 404 }); } // Check if user is authorized (creator or commissioner) const userIsCommissioner = await isCommissioner(leagueId, userId); const isCreator = league.createdBy === userId; if (!isCreator && !userIsCommissioner) { throw new Response("Forbidden - You must be a commissioner to access settings", { status: 403, }); } // Get current season to count teams const season = await findCurrentSeason(leagueId); const teams = season ? await findTeamsBySeasonId(season.id) : []; return { league, teamCount: teams.length, }; } export async function action(args: Route.ActionArgs) { const { userId } = await getAuth(args); const { params, request } = args; const { leagueId } = params; if (!userId) { throw new Response("Unauthorized", { status: 401 }); } // Verify authorization const league = await findLeagueById(leagueId); if (!league) { throw new Response("League not found", { status: 404 }); } const userIsCommissioner = await isCommissioner(leagueId, userId); const isCreator = league.createdBy === userId; if (!isCreator && !userIsCommissioner) { throw new Response("Forbidden", { status: 403 }); } const formData = await request.formData(); const intent = formData.get("intent"); if (intent === "delete") { // Delete the league await deleteLeague(leagueId); // Redirect to home with success message return redirect("/?deleted=true"); } if (intent === "update") { const name = formData.get("name"); // Validation if (typeof name !== "string" || !name.trim()) { return { error: "League name is required" }; } if (name.trim().length < 3 || name.trim().length > 50) { return { error: "League name must be between 3 and 50 characters" }; } try { await updateLeague(leagueId, { name: name.trim(), }); return { success: "League updated successfully" }; } catch (error) { console.error("Error updating league:", error); return { error: "Failed to update league. Please try again." }; } } return { error: "Invalid action" }; } export default function LeagueSettings({ loaderData, actionData }: Route.ComponentProps) { const { league, teamCount } = loaderData; const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const handleDelete = () => { setIsDeleteDialogOpen(false); // The form submission will handle the actual deletion }; return (

League Settings

{league.name}

{/* Update League Form */} General Settings Update your league's basic information

Team count cannot be changed after league creation

{actionData?.success && (
{actionData.success}
)} {actionData?.error && (
{actionData.error}
)}
{/* Danger Zone */} Danger Zone Irreversible and destructive actions Are you absolutely sure? This will permanently delete {league.name} and all associated data including seasons, teams, and commissioners. This action cannot be undone. Cancel
Delete League
); }