feat: add team settings route and logo URL field to teams table
This commit is contained in:
parent
025ba82cb2
commit
6c0684f3d7
7 changed files with 1208 additions and 9 deletions
|
|
@ -6,6 +6,7 @@ export default [
|
|||
route("leagues/new", "routes/leagues/new.tsx"),
|
||||
route("leagues/:leagueId", "routes/leagues/$leagueId.tsx"),
|
||||
route("leagues/:leagueId/settings", "routes/leagues/$leagueId.settings.tsx"),
|
||||
route("teams/:teamId/settings", "routes/teams/$teamId.settings.tsx"),
|
||||
route("api/webhooks/clerk", "routes/api/webhooks/clerk.ts"),
|
||||
route("user-profile", "routes/user-profile.tsx"),
|
||||
route("how-to-play", "routes/how-to-play.tsx"),
|
||||
|
|
|
|||
|
|
@ -134,13 +134,17 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
|||
|
||||
useEffect(() => {
|
||||
if (searchParams.get("updated") === "true") {
|
||||
toast.success("League updated successfully");
|
||||
toast.success("Team updated successfully");
|
||||
setSearchParams({});
|
||||
}
|
||||
if (searchParams.get("joined") === "true") {
|
||||
toast.success("Welcome to the league! You've been assigned a team.");
|
||||
setSearchParams({});
|
||||
}
|
||||
if (searchParams.get("left") === "true") {
|
||||
toast.success("You have left the league. Your team is now available.");
|
||||
setSearchParams({});
|
||||
}
|
||||
}, [searchParams, setSearchParams]);
|
||||
|
||||
const handleCopyInviteLink = async () => {
|
||||
|
|
@ -163,14 +167,22 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
|||
<div className="flex items-center justify-between mb-2">
|
||||
<h1 className="text-4xl font-bold">{league.name}</h1>
|
||||
<div className="flex gap-2">
|
||||
{isUserCommissioner && (
|
||||
{teams.find((t) => t.ownerId === currentUserId) && (
|
||||
<Button variant="outline" asChild>
|
||||
<Link to={`/leagues/${league.id}/settings`}>Settings</Link>
|
||||
<Link
|
||||
to={`/teams/${teams.find((t) => t.ownerId === currentUserId)?.id}/settings`}
|
||||
>
|
||||
Team Settings
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
{isUserCommissioner && (
|
||||
<Button variant="outline" asChild>
|
||||
<Link to="/">Back to Home</Link>
|
||||
<Link to={`/leagues/${league.id}/settings`}>
|
||||
League Settings
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{season && (
|
||||
|
|
@ -224,14 +236,17 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
|||
<CardHeader>
|
||||
<CardTitle>Teams</CardTitle>
|
||||
<CardDescription>
|
||||
{teams.length} team{teams.length !== 1 ? "s" : ""} in this league
|
||||
{teams.length} team{teams.length !== 1 ? "s" : ""} in this
|
||||
league
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-3">
|
||||
{teams.map((team) => {
|
||||
const isOwned = team.ownerId === currentUserId;
|
||||
const ownerName = team.ownerId ? ownerMap[team.ownerId] : null;
|
||||
const ownerName = team.ownerId
|
||||
? ownerMap[team.ownerId]
|
||||
: null;
|
||||
return (
|
||||
<Card
|
||||
key={team.id}
|
||||
|
|
@ -307,7 +322,9 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
|||
<p className="font-medium">
|
||||
{commissionerName || "Unknown User"}
|
||||
{commissioner.userId === currentUserId && (
|
||||
<span className="ml-2 text-xs text-primary">(You)</span>
|
||||
<span className="ml-2 text-xs text-primary">
|
||||
(You)
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
213
app/routes/teams/$teamId.settings.tsx
Normal file
213
app/routes/teams/$teamId.settings.tsx
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
import { Form, redirect, useNavigate } from "react-router";
|
||||
import { getAuth } from "@clerk/react-router/server";
|
||||
import type { Route } from "./+types/$teamId.settings";
|
||||
import {
|
||||
findTeamById,
|
||||
updateTeam,
|
||||
removeTeamOwner,
|
||||
} from "~/models/team";
|
||||
import { findSeasonById } from "~/models/season";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import { Input } from "~/components/ui/input";
|
||||
import { Label } from "~/components/ui/label";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "~/components/ui/alert-dialog";
|
||||
|
||||
export async function loader(args: Route.LoaderArgs) {
|
||||
const { params } = args;
|
||||
const { teamId } = params;
|
||||
const { userId } = await getAuth(args);
|
||||
|
||||
if (!userId) {
|
||||
throw new Response("You must be logged in", { status: 401 });
|
||||
}
|
||||
|
||||
const team = await findTeamById(teamId);
|
||||
|
||||
if (!team) {
|
||||
throw new Response("Team not found", { status: 404 });
|
||||
}
|
||||
|
||||
// Only the team owner can access settings
|
||||
if (team.ownerId !== userId) {
|
||||
throw new Response("You do not have access to this team", { status: 403 });
|
||||
}
|
||||
|
||||
const season = await findSeasonById(team.seasonId);
|
||||
|
||||
if (!season) {
|
||||
throw new Response("Season not found", { status: 404 });
|
||||
}
|
||||
|
||||
return { team, season };
|
||||
}
|
||||
|
||||
export async function action(args: Route.ActionArgs) {
|
||||
const { params, request } = args;
|
||||
const { teamId } = params;
|
||||
const { userId } = await getAuth(args);
|
||||
|
||||
if (!userId) {
|
||||
throw new Response("You must be logged in", { status: 401 });
|
||||
}
|
||||
|
||||
const team = await findTeamById(teamId);
|
||||
|
||||
if (!team) {
|
||||
throw new Response("Team not found", { status: 404 });
|
||||
}
|
||||
|
||||
// Only the team owner can modify settings
|
||||
if (team.ownerId !== userId) {
|
||||
throw new Response("You do not have access to this team", { status: 403 });
|
||||
}
|
||||
|
||||
const formData = await request.formData();
|
||||
const intent = formData.get("intent");
|
||||
|
||||
if (intent === "update") {
|
||||
const name = formData.get("name");
|
||||
const logoUrl = formData.get("logoUrl");
|
||||
|
||||
if (!name || typeof name !== "string") {
|
||||
return { error: "Team name is required" };
|
||||
}
|
||||
|
||||
await updateTeam(teamId, {
|
||||
name: name.trim(),
|
||||
logoUrl: logoUrl && typeof logoUrl === "string" ? logoUrl.trim() : undefined,
|
||||
});
|
||||
|
||||
const season = await findSeasonById(team.seasonId);
|
||||
return redirect(`/leagues/${season?.leagueId}?updated=true`);
|
||||
}
|
||||
|
||||
if (intent === "leave") {
|
||||
await removeTeamOwner(teamId);
|
||||
const season = await findSeasonById(team.seasonId);
|
||||
return redirect(`/leagues/${season?.leagueId}?left=true`);
|
||||
}
|
||||
|
||||
return { error: "Invalid action" };
|
||||
}
|
||||
|
||||
export default function TeamSettings({ loaderData }: Route.ComponentProps) {
|
||||
const { team, season } = loaderData;
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-8 px-4">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h1 className="text-4xl font-bold">Team Settings</h1>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => navigate(`/leagues/${season.leagueId}`)}
|
||||
>
|
||||
Back to League
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-muted-foreground">
|
||||
Manage your team settings and preferences
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Team Information</CardTitle>
|
||||
<CardDescription>
|
||||
Update your team name and logo
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form method="post" className="space-y-4">
|
||||
<input type="hidden" name="intent" value="update" />
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Team Name</Label>
|
||||
<Input
|
||||
id="name"
|
||||
name="name"
|
||||
type="text"
|
||||
defaultValue={team.name}
|
||||
required
|
||||
maxLength={255}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="logoUrl">Team Logo URL (optional)</Label>
|
||||
<Input
|
||||
id="logoUrl"
|
||||
name="logoUrl"
|
||||
type="url"
|
||||
defaultValue={team.logoUrl || ""}
|
||||
placeholder="https://example.com/logo.png"
|
||||
maxLength={512}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Enter a URL to an image for your team logo
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Button type="submit">Save Changes</Button>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-destructive">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-destructive">Danger Zone</CardTitle>
|
||||
<CardDescription>
|
||||
Irreversible actions for your team
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive">Leave League</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will remove you as the owner of "{team.name}" and make the team
|
||||
available for others to claim. This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<Form method="post">
|
||||
<input type="hidden" name="intent" value="leave" />
|
||||
<AlertDialogAction type="submit" className="bg-destructive hover:bg-destructive/90">
|
||||
Leave League
|
||||
</AlertDialogAction>
|
||||
</Form>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -79,6 +79,7 @@ export const teams = pgTable("teams", {
|
|||
.notNull()
|
||||
.references(() => seasons.id, { onDelete: "cascade" }),
|
||||
name: varchar("name", { length: 255 }).notNull(),
|
||||
logoUrl: varchar("logo_url", { length: 512 }),
|
||||
ownerId: varchar("owner_id", { length: 255 }), // Clerk user ID, nullable
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
|
|
|
|||
1
drizzle/0012_yielding_phil_sheldon.sql
Normal file
1
drizzle/0012_yielding_phil_sheldon.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE "teams" ADD COLUMN "logo_url" varchar(512);
|
||||
959
drizzle/meta/0012_snapshot.json
Normal file
959
drizzle/meta/0012_snapshot.json
Normal file
|
|
@ -0,0 +1,959 @@
|
|||
{
|
||||
"id": "18540fa4-0d1d-4b45-914b-4bf80ad5dadd",
|
||||
"prevId": "93dd6587-4fbf-4269-8777-db6a88e40d38",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.commissioners": {
|
||||
"name": "commissioners",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"league_id": {
|
||||
"name": "league_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"commissioners_league_id_leagues_id_fk": {
|
||||
"name": "commissioners_league_id_leagues_id_fk",
|
||||
"tableFrom": "commissioners",
|
||||
"tableTo": "leagues",
|
||||
"columnsFrom": [
|
||||
"league_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.leagues": {
|
||||
"name": "leagues",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_by": {
|
||||
"name": "created_by",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"current_season_id": {
|
||||
"name": "current_season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.participant_results": {
|
||||
"name": "participant_results",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"participant_id": {
|
||||
"name": "participant_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"sports_season_id": {
|
||||
"name": "sports_season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"final_position": {
|
||||
"name": "final_position",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"points_awarded": {
|
||||
"name": "points_awarded",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
},
|
||||
"qualifying_points": {
|
||||
"name": "qualifying_points",
|
||||
"type": "numeric(10, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"notes": {
|
||||
"name": "notes",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"participant_results_participant_id_participants_id_fk": {
|
||||
"name": "participant_results_participant_id_participants_id_fk",
|
||||
"tableFrom": "participant_results",
|
||||
"tableTo": "participants",
|
||||
"columnsFrom": [
|
||||
"participant_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"participant_results_sports_season_id_sports_seasons_id_fk": {
|
||||
"name": "participant_results_sports_season_id_sports_seasons_id_fk",
|
||||
"tableFrom": "participant_results",
|
||||
"tableTo": "sports_seasons",
|
||||
"columnsFrom": [
|
||||
"sports_season_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.participants": {
|
||||
"name": "participants",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"sports_season_id": {
|
||||
"name": "sports_season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"short_name": {
|
||||
"name": "short_name",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"external_id": {
|
||||
"name": "external_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"participants_sports_season_id_sports_seasons_id_fk": {
|
||||
"name": "participants_sports_season_id_sports_seasons_id_fk",
|
||||
"tableFrom": "participants",
|
||||
"tableTo": "sports_seasons",
|
||||
"columnsFrom": [
|
||||
"sports_season_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.season_sports": {
|
||||
"name": "season_sports",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"season_id": {
|
||||
"name": "season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"sports_season_id": {
|
||||
"name": "sports_season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"season_sports_season_id_seasons_id_fk": {
|
||||
"name": "season_sports_season_id_seasons_id_fk",
|
||||
"tableFrom": "season_sports",
|
||||
"tableTo": "seasons",
|
||||
"columnsFrom": [
|
||||
"season_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"season_sports_sports_season_id_sports_seasons_id_fk": {
|
||||
"name": "season_sports_sports_season_id_sports_seasons_id_fk",
|
||||
"tableFrom": "season_sports",
|
||||
"tableTo": "sports_seasons",
|
||||
"columnsFrom": [
|
||||
"sports_season_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.season_template_sports": {
|
||||
"name": "season_template_sports",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"template_id": {
|
||||
"name": "template_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"sports_season_id": {
|
||||
"name": "sports_season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"season_template_sports_template_id_season_templates_id_fk": {
|
||||
"name": "season_template_sports_template_id_season_templates_id_fk",
|
||||
"tableFrom": "season_template_sports",
|
||||
"tableTo": "season_templates",
|
||||
"columnsFrom": [
|
||||
"template_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"season_template_sports_sports_season_id_sports_seasons_id_fk": {
|
||||
"name": "season_template_sports_sports_season_id_sports_seasons_id_fk",
|
||||
"tableFrom": "season_template_sports",
|
||||
"tableTo": "sports_seasons",
|
||||
"columnsFrom": [
|
||||
"sports_season_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.season_templates": {
|
||||
"name": "season_templates",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"year": {
|
||||
"name": "year",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"is_active": {
|
||||
"name": "is_active",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.seasons": {
|
||||
"name": "seasons",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"league_id": {
|
||||
"name": "league_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"year": {
|
||||
"name": "year",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "season_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'pre_draft'"
|
||||
},
|
||||
"template_id": {
|
||||
"name": "template_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"flex_spots": {
|
||||
"name": "flex_spots",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
},
|
||||
"invite_code": {
|
||||
"name": "invite_code",
|
||||
"type": "varchar(20)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"seasons_league_id_leagues_id_fk": {
|
||||
"name": "seasons_league_id_leagues_id_fk",
|
||||
"tableFrom": "seasons",
|
||||
"tableTo": "leagues",
|
||||
"columnsFrom": [
|
||||
"league_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"seasons_template_id_season_templates_id_fk": {
|
||||
"name": "seasons_template_id_season_templates_id_fk",
|
||||
"tableFrom": "seasons",
|
||||
"tableTo": "season_templates",
|
||||
"columnsFrom": [
|
||||
"template_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"seasons_invite_code_unique": {
|
||||
"name": "seasons_invite_code_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"invite_code"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.sports": {
|
||||
"name": "sports",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "sport_type",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"icon_url": {
|
||||
"name": "icon_url",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sports_slug_unique": {
|
||||
"name": "sports_slug_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"slug"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.sports_seasons": {
|
||||
"name": "sports_seasons",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"sport_id": {
|
||||
"name": "sport_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"year": {
|
||||
"name": "year",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"start_date": {
|
||||
"name": "start_date",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"end_date": {
|
||||
"name": "end_date",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "sports_season_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'upcoming'"
|
||||
},
|
||||
"scoring_type": {
|
||||
"name": "scoring_type",
|
||||
"type": "scoring_type",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sports_seasons_sport_id_sports_id_fk": {
|
||||
"name": "sports_seasons_sport_id_sports_id_fk",
|
||||
"tableFrom": "sports_seasons",
|
||||
"tableTo": "sports",
|
||||
"columnsFrom": [
|
||||
"sport_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.teams": {
|
||||
"name": "teams",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"season_id": {
|
||||
"name": "season_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"logo_url": {
|
||||
"name": "logo_url",
|
||||
"type": "varchar(512)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"owner_id": {
|
||||
"name": "owner_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"teams_season_id_seasons_id_fk": {
|
||||
"name": "teams_season_id_seasons_id_fk",
|
||||
"tableFrom": "teams",
|
||||
"tableTo": "seasons",
|
||||
"columnsFrom": [
|
||||
"season_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"clerk_id": {
|
||||
"name": "clerk_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"display_name": {
|
||||
"name": "display_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"first_name": {
|
||||
"name": "first_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"last_name": {
|
||||
"name": "last_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"image_url": {
|
||||
"name": "image_url",
|
||||
"type": "varchar(512)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_admin": {
|
||||
"name": "is_admin",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"users_clerk_id_unique": {
|
||||
"name": "users_clerk_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"clerk_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.scoring_type": {
|
||||
"name": "scoring_type",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"playoffs",
|
||||
"regular_season",
|
||||
"majors"
|
||||
]
|
||||
},
|
||||
"public.season_status": {
|
||||
"name": "season_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"pre_draft",
|
||||
"draft",
|
||||
"active",
|
||||
"completed"
|
||||
]
|
||||
},
|
||||
"public.sport_type": {
|
||||
"name": "sport_type",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"team",
|
||||
"individual"
|
||||
]
|
||||
},
|
||||
"public.sports_season_status": {
|
||||
"name": "sports_season_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"upcoming",
|
||||
"active",
|
||||
"completed"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"roles": {},
|
||||
"policies": {},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,6 +85,13 @@
|
|||
"when": 1760501621605,
|
||||
"tag": "0011_gifted_mystique",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1760504208398,
|
||||
"tag": "0012_yielding_phil_sheldon",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue