import { Form } from "react-router"; import type { Route } from "./+types/admin.standings-snapshots"; import { database } from "~/database/context"; import { eq, or } from "drizzle-orm"; import * as schema from "~/database/schema"; import { createDailySnapshot } from "~/models/standings"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { Button } from "~/components/ui/button"; import { Badge } from "~/components/ui/badge"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "~/components/ui/table"; import { Calendar, RefreshCw, CheckCircle2, AlertCircle } from "lucide-react"; export function meta(): Route.MetaDescriptors { return [{ title: "Standings Snapshots - Brackt Admin" }]; } export async function loader() { const db = database(); // Get all active and draft seasons const seasons = await db.query.seasons.findMany({ where: or( eq(schema.seasons.status, "active"), eq(schema.seasons.status, "draft") ), with: { league: true, }, orderBy: (s, { desc }) => [desc(s.createdAt)], }); // For each season, get the most recent snapshot const seasonsWithSnapshots = await Promise.all( seasons.map(async (season) => { const mostRecentSnapshot = await db.query.teamStandingsSnapshots.findFirst({ where: eq(schema.teamStandingsSnapshots.seasonId, season.id), orderBy: (snapshots, { desc }) => [desc(snapshots.snapshotDate)], }); return { ...season, lastSnapshotDate: mostRecentSnapshot?.snapshotDate || null, lastSnapshotTime: mostRecentSnapshot?.createdAt || null, }; }) ); return { seasons: seasonsWithSnapshots, }; } export async function action({ request }: Route.ActionArgs) { const db = database(); const formData = await request.formData(); const intent = formData.get("intent"); const seasonId = formData.get("seasonId") as string; try { if (intent === "create-snapshot") { if (seasonId === "all") { // Create snapshots for all active seasons const seasons = await db.query.seasons.findMany({ where: or( eq(schema.seasons.status, "active"), eq(schema.seasons.status, "draft") ), }); for (const season of seasons) { await createDailySnapshot(season.id, db); } return { success: true, message: `Created snapshots for ${seasons.length} season(s)`, }; } else { // Create snapshot for specific season await createDailySnapshot(seasonId, db); return { success: true, message: "Snapshot created successfully", }; } } return { success: false, message: "Invalid intent", }; } catch (error) { console.error("Error creating snapshot:", error); return { success: false, message: error instanceof Error ? error.message : "Unknown error", }; } } export default function AdminStandingsSnapshots({ loaderData, actionData, }: Route.ComponentProps) { const { seasons } = loaderData; const today = new Date().toISOString().split("T")[0]; return (
Manage daily standings snapshots for historical tracking and 7-day comparison
{actionData.message}
Automatic Snapshots: The system creates snapshots once per day for all active seasons that don't already have a snapshot for today.
Manual Snapshots: Use the "Create Snapshot" buttons below to manually trigger snapshot creation for specific seasons or all active seasons.
7-Day Comparison: Standings pages show movement indicators comparing current rank to the snapshot from 7 days ago.
No active or draft seasons found