2025-10-12 21:54:49 -07:00
|
|
|
import { Link } from "react-router";
|
|
|
|
|
import type { Route } from "./+types/admin.sports";
|
2025-10-13 10:30:47 -07:00
|
|
|
import { findAllSportsWithActiveSeasons } from "~/models/sport";
|
2025-10-12 21:54:49 -07:00
|
|
|
import {
|
|
|
|
|
Card,
|
|
|
|
|
CardContent,
|
|
|
|
|
CardDescription,
|
|
|
|
|
CardHeader,
|
|
|
|
|
CardTitle,
|
|
|
|
|
} from "~/components/ui/card";
|
|
|
|
|
import { Button } from "~/components/ui/button";
|
|
|
|
|
import { Plus, Trophy } from "lucide-react";
|
|
|
|
|
import {
|
|
|
|
|
Table,
|
|
|
|
|
TableBody,
|
|
|
|
|
TableCell,
|
|
|
|
|
TableHead,
|
|
|
|
|
TableHeader,
|
|
|
|
|
TableRow,
|
|
|
|
|
} from "~/components/ui/table";
|
|
|
|
|
import { Badge } from "~/components/ui/badge";
|
|
|
|
|
|
|
|
|
|
export async function loader() {
|
2025-10-13 10:30:47 -07:00
|
|
|
const sports = await findAllSportsWithActiveSeasons();
|
2025-10-12 21:54:49 -07:00
|
|
|
return { sports };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function AdminSports({ loaderData }: Route.ComponentProps) {
|
|
|
|
|
const { sports } = loaderData;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="p-8">
|
|
|
|
|
<div className="flex items-center justify-between mb-6">
|
|
|
|
|
<div>
|
|
|
|
|
<h1 className="text-3xl font-bold">Sports</h1>
|
|
|
|
|
<p className="text-muted-foreground mt-1">
|
|
|
|
|
Manage all sports in the system
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<Button asChild>
|
|
|
|
|
<Link to="/admin/sports/new">
|
|
|
|
|
<Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
Add Sport
|
|
|
|
|
</Link>
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Card>
|
|
|
|
|
<CardHeader>
|
|
|
|
|
<CardTitle>All Sports</CardTitle>
|
|
|
|
|
<CardDescription>
|
|
|
|
|
{sports.length} {sports.length === 1 ? "sport" : "sports"} total
|
|
|
|
|
</CardDescription>
|
|
|
|
|
</CardHeader>
|
|
|
|
|
<CardContent>
|
|
|
|
|
{sports.length === 0 ? (
|
|
|
|
|
<div className="text-center py-12">
|
|
|
|
|
<Trophy className="mx-auto h-12 w-12 text-muted-foreground" />
|
|
|
|
|
<h3 className="mt-4 text-lg font-semibold">No sports yet</h3>
|
|
|
|
|
<p className="text-muted-foreground mt-2">
|
|
|
|
|
Get started by creating your first sport
|
|
|
|
|
</p>
|
|
|
|
|
<Button className="mt-4" asChild>
|
|
|
|
|
<Link to="/admin/sports/new">
|
|
|
|
|
<Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
Add Sport
|
|
|
|
|
</Link>
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<Table>
|
|
|
|
|
<TableHeader>
|
|
|
|
|
<TableRow>
|
|
|
|
|
<TableHead>Name</TableHead>
|
|
|
|
|
<TableHead>Type</TableHead>
|
|
|
|
|
<TableHead>Slug</TableHead>
|
2025-10-13 10:30:47 -07:00
|
|
|
<TableHead>Current Seasons</TableHead>
|
2025-10-12 21:54:49 -07:00
|
|
|
<TableHead className="text-right">Actions</TableHead>
|
|
|
|
|
</TableRow>
|
|
|
|
|
</TableHeader>
|
|
|
|
|
<TableBody>
|
|
|
|
|
{sports.map((sport) => (
|
|
|
|
|
<TableRow key={sport.id}>
|
|
|
|
|
<TableCell className="font-medium">{sport.name}</TableCell>
|
|
|
|
|
<TableCell>
|
|
|
|
|
<Badge variant={sport.type === "team" ? "default" : "secondary"}>
|
|
|
|
|
{sport.type}
|
|
|
|
|
</Badge>
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell className="text-muted-foreground">
|
|
|
|
|
{sport.slug}
|
|
|
|
|
</TableCell>
|
2025-10-13 10:30:47 -07:00
|
|
|
<TableCell>
|
|
|
|
|
{sport.activeSeasons.length > 0 ? (
|
|
|
|
|
<div className="flex flex-col gap-1">
|
|
|
|
|
{sport.activeSeasons.map((season) => (
|
|
|
|
|
<Link
|
|
|
|
|
key={season.id}
|
|
|
|
|
to={`/admin/sports-seasons/${season.id}`}
|
|
|
|
|
className="text-sm text-primary hover:underline"
|
|
|
|
|
>
|
|
|
|
|
{season.name} ({season.year})
|
|
|
|
|
</Link>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<span className="text-sm text-muted-foreground">
|
|
|
|
|
No current seasons
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
</TableCell>
|
2025-10-12 21:54:49 -07:00
|
|
|
<TableCell className="text-right">
|
|
|
|
|
<Button variant="ghost" size="sm" asChild>
|
|
|
|
|
<Link to={`/admin/sports/${sport.id}`}>Edit</Link>
|
|
|
|
|
</Button>
|
|
|
|
|
</TableCell>
|
|
|
|
|
</TableRow>
|
|
|
|
|
))}
|
|
|
|
|
</TableBody>
|
|
|
|
|
</Table>
|
|
|
|
|
)}
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|