brackt/app/routes/home.tsx

145 lines
4.4 KiB
TypeScript
Raw Normal View History

import { useEffect } from "react";
import { Link, useSearchParams } from "react-router";
import { toast } from "sonner";
import { getAuth } from "@clerk/react-router/server";
import type { Route } from "./+types/home";
import { findLeaguesWithActiveSeasonsByUserId } from "~/models/league";
import { findSeasonById } from "~/models/season";
import { Button } from "~/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "~/components/ui/card";
export function meta() {
return [
{ title: "Brackt - Fantasy All of the Sports!" },
{
name: "description",
content: "Play multi-sport fantasy leagues with your friends!",
},
];
}
export async function loader(args: Route.LoaderArgs) {
const { userId } = await getAuth(args);
if (!userId) {
return { leagues: [], isLoggedIn: false };
}
// Fetch leagues where user has a team in the current season
const leagues = await findLeaguesWithActiveSeasonsByUserId(userId);
// Fetch season details for each league's current season
const leaguesWithSeasons = await Promise.all(
leagues.map(async (league) => {
const season = league.currentSeasonId
? await findSeasonById(league.currentSeasonId)
: null;
return {
...league,
currentSeason: season,
};
})
);
return {
leagues: leaguesWithSeasons,
isLoggedIn: true,
};
}
export default function Home({ loaderData }: Route.ComponentProps) {
const { leagues, isLoggedIn } = loaderData;
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => {
if (searchParams.get("deleted") === "true") {
toast.success("League deleted successfully");
setSearchParams({});
}
}, [searchParams, setSearchParams]);
if (!isLoggedIn) {
return (
<div className="container mx-auto py-16 px-4 text-center">
<h1 className="text-4xl font-bold mb-4">Welcome to Brackt</h1>
<p className="text-xl text-muted-foreground mb-8">
Please sign in to view your leagues
</p>
</div>
);
}
return (
<div className="container mx-auto py-8 px-4">
<div className="flex items-center justify-between mb-8">
<h1 className="text-4xl font-bold">My Leagues</h1>
<Button asChild>
<Link to="/leagues/new">Create New League</Link>
</Button>
</div>
{leagues.length === 0 ? (
<Card>
<CardHeader>
<CardTitle>No Active Leagues</CardTitle>
<CardDescription>
You don't have any teams in leagues with active seasons yet
</CardDescription>
</CardHeader>
<CardContent>
<Button asChild>
<Link to="/leagues/new">Create a New League</Link>
</Button>
</CardContent>
</Card>
) : (
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{leagues.map((league) => (
<Link key={league.id} to={`/leagues/${league.id}`}>
<Card className="hover:border-primary transition-colors cursor-pointer h-full">
<CardHeader>
<CardTitle>{league.name}</CardTitle>
<CardDescription>
Created {new Date(league.createdAt).toLocaleDateString()}
</CardDescription>
</CardHeader>
<CardContent>
{league.currentSeason ? (
<div className="space-y-2">
<div>
<p className="text-sm text-muted-foreground">
Current Season
</p>
<p className="font-medium">
{league.currentSeason.year}
</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Status</p>
<p className="font-medium capitalize">
{league.currentSeason.status.replace("_", " ")}
</p>
</div>
</div>
) : (
<p className="text-sm text-muted-foreground">
No active season
</p>
)}
</CardContent>
</Card>
</Link>
))}
</div>
)}
</div>
);
}