170 lines
6.4 KiB
TypeScript
170 lines
6.4 KiB
TypeScript
import { Link } from "react-router";
|
|
import type { Route } from "./+types/admin._index";
|
|
import { findAllSports } from "~/models/sport";
|
|
import { findAllSportsSeasons } from "~/models/sports-season";
|
|
import { findAllSeasonTemplates } from "~/models/season-template";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "~/components/ui/card";
|
|
import { Button } from "~/components/ui/button";
|
|
import { Trophy, Calendar, FolderKanban, ArrowRight } from "lucide-react";
|
|
|
|
export async function loader() {
|
|
const [sports, sportsSeasons, templates] = await Promise.all([
|
|
findAllSports(),
|
|
findAllSportsSeasons(),
|
|
findAllSeasonTemplates(),
|
|
]);
|
|
|
|
return {
|
|
stats: {
|
|
sportsCount: sports.length,
|
|
sportsSeasonsCount: sportsSeasons.length,
|
|
templatesCount: templates.length,
|
|
},
|
|
};
|
|
}
|
|
|
|
export default function AdminDashboard({ loaderData }: Route.ComponentProps) {
|
|
const { stats } = loaderData;
|
|
|
|
return (
|
|
<div className="p-8">
|
|
<div className="mb-8">
|
|
<h1 className="text-3xl font-bold">Admin Dashboard</h1>
|
|
<p className="text-muted-foreground mt-2">
|
|
Manage sports, seasons, participants, and templates
|
|
</p>
|
|
</div>
|
|
|
|
<div className="grid gap-6 md:grid-cols-3 mb-8">
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Total Sports</CardTitle>
|
|
<Trophy className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">{stats.sportsCount}</div>
|
|
<p className="text-xs text-muted-foreground mt-1">
|
|
Active sports in the system
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">
|
|
Sports Seasons
|
|
</CardTitle>
|
|
<Calendar className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">{stats.sportsSeasonsCount}</div>
|
|
<p className="text-xs text-muted-foreground mt-1">
|
|
Across all sports
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Templates</CardTitle>
|
|
<FolderKanban className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-2xl font-bold">{stats.templatesCount}</div>
|
|
<p className="text-xs text-muted-foreground mt-1">
|
|
Season templates available
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
<div className="grid gap-6 md:grid-cols-2">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Quick Actions</CardTitle>
|
|
<CardDescription>Common administrative tasks</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-2">
|
|
<Button variant="outline" className="w-full justify-between" asChild>
|
|
<Link to="/admin/sports/new">
|
|
Create New Sport
|
|
<ArrowRight className="h-4 w-4" />
|
|
</Link>
|
|
</Button>
|
|
<Button variant="outline" className="w-full justify-between" asChild>
|
|
<Link to="/admin/sports-seasons/new">
|
|
Create Sports Season
|
|
<ArrowRight className="h-4 w-4" />
|
|
</Link>
|
|
</Button>
|
|
<Button variant="outline" className="w-full justify-between" asChild>
|
|
<Link to="/admin/templates/new">
|
|
Create Season Template
|
|
<ArrowRight className="h-4 w-4" />
|
|
</Link>
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Getting Started</CardTitle>
|
|
<CardDescription>Set up your sports system</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<div className="flex items-start space-x-3">
|
|
<div className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-medium">
|
|
1
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="text-sm font-medium">Create Sports</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
Add sports like NFL, NBA, Golf, etc.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-start space-x-3">
|
|
<div className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-medium">
|
|
2
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="text-sm font-medium">Create Sports Seasons</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
Add specific seasons for each sport
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-start space-x-3">
|
|
<div className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-medium">
|
|
3
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="text-sm font-medium">Add Participants</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
Add teams or players to each sports season
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-start space-x-3">
|
|
<div className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-medium">
|
|
4
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="text-sm font-medium">Create Templates</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
Bundle sports seasons into templates for leagues
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|