From 48bca99f3760c416b460283b54a69bca4e9357fb Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Sat, 11 Oct 2025 01:03:31 -0700 Subject: [PATCH] refactor: remove guest book feature and update league settings success flow --- app/routes/home.tsx | 48 +-- app/routes/leagues/$leagueId.settings.tsx | 8 +- app/routes/leagues/$leagueId.tsx | 25 +- app/welcome/welcome.tsx | 66 +---- database/schema.ts | 6 - drizzle/0005_abnormal_thunderbird.sql | 1 + drizzle/meta/0005_snapshot.json | 341 ++++++++++++++++++++++ drizzle/meta/_journal.json | 7 + 8 files changed, 375 insertions(+), 127 deletions(-) create mode 100644 drizzle/0005_abnormal_thunderbird.sql create mode 100644 drizzle/meta/0005_snapshot.json diff --git a/app/routes/home.tsx b/app/routes/home.tsx index ba3695f..f78a00e 100644 --- a/app/routes/home.tsx +++ b/app/routes/home.tsx @@ -1,7 +1,5 @@ import { useEffect } from "react"; import { useSearchParams } from "react-router"; -import { database } from "~/database/context"; -import * as schema from "~/database/schema"; import { toast } from "sonner"; import type { Route } from "./+types/home"; @@ -9,50 +7,18 @@ import { Welcome } from "../welcome/welcome"; export function meta({}: Route.MetaArgs) { return [ - { title: "New React Router App" }, - { name: "description", content: "Welcome to React Router!" }, + { title: "Brackt - Fantasy Sports Brackets" }, + { name: "description", content: "Create and manage your fantasy sports leagues" }, ]; } -export async function action({ request }: Route.ActionArgs) { - const formData = await request.formData(); - let name = formData.get("name"); - let email = formData.get("email"); - if (typeof name !== "string" || typeof email !== "string") { - return { guestBookError: "Name and email are required" }; - } - - name = name.trim(); - email = email.trim(); - if (!name || !email) { - return { guestBookError: "Name and email are required" }; - } - - const db = database(); - try { - await db.insert(schema.guestBook).values({ name, email }); - } catch (error) { - return { guestBookError: "Error adding to guest book" }; - } -} - export async function loader({ context }: Route.LoaderArgs) { - const db = database(); - - const guestBook = await db.query.guestBook.findMany({ - columns: { - id: true, - name: true, - }, - }); - return { - guestBook, message: context.VALUE_FROM_EXPRESS, }; } -export default function Home({ actionData, loaderData }: Route.ComponentProps) { +export default function Home({ loaderData }: Route.ComponentProps) { const [searchParams, setSearchParams] = useSearchParams(); useEffect(() => { @@ -63,11 +29,5 @@ export default function Home({ actionData, loaderData }: Route.ComponentProps) { } }, [searchParams, setSearchParams]); - return ( - - ); + return ; } diff --git a/app/routes/leagues/$leagueId.settings.tsx b/app/routes/leagues/$leagueId.settings.tsx index 4607400..d85606b 100644 --- a/app/routes/leagues/$leagueId.settings.tsx +++ b/app/routes/leagues/$leagueId.settings.tsx @@ -121,7 +121,7 @@ export async function action(args: Route.ActionArgs) { name: name.trim(), }); - return { success: "League updated successfully" }; + return redirect(`/leagues/${leagueId}?updated=true`); } catch (error) { console.error("Error updating league:", error); return { error: "Failed to update league. Please try again." }; @@ -198,12 +198,6 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone

- {actionData?.success && ( -
- {actionData.success} -
- )} - {actionData?.error && (
{actionData.error} diff --git a/app/routes/leagues/$leagueId.tsx b/app/routes/leagues/$leagueId.tsx index 0bc5dea..e56525e 100644 --- a/app/routes/leagues/$leagueId.tsx +++ b/app/routes/leagues/$leagueId.tsx @@ -1,10 +1,15 @@ -import { Link } from "react-router"; +import { useEffect } from "react"; +import { Link, useSearchParams } from "react-router"; import { getAuth } from "@clerk/react-router/server"; -import { findLeagueById } from "~/models/league"; -import { findCurrentSeason } from "~/models/season"; -import { findTeamsBySeasonId } from "~/models/team"; -import { findCommissionersByLeagueId } from "~/models/commissioner"; +import { toast } from "sonner"; +import { + findLeagueById, + findCurrentSeason, + findTeamsBySeasonId, + findCommissionersByLeagueId, +} from "~/models"; import type { Route } from "./+types/$leagueId"; +import { Button } from "~/components/ui/button"; import { Card, CardContent, @@ -12,7 +17,6 @@ import { CardHeader, CardTitle, } from "~/components/ui/card"; -import { Button } from "~/components/ui/button"; export async function loader(args: Route.LoaderArgs) { const { userId } = await getAuth(args); @@ -50,6 +54,15 @@ export async function loader(args: Route.LoaderArgs) { export default function LeagueHome({ loaderData }: Route.ComponentProps) { const { league, season, teams, commissioners, currentUserId, isUserCommissioner } = loaderData; + const [searchParams, setSearchParams] = useSearchParams(); + + useEffect(() => { + if (searchParams.get("updated") === "true") { + toast.success("League updated successfully"); + // Remove the query parameter + setSearchParams({}); + } + }, [searchParams, setSearchParams]); return (
diff --git a/app/welcome/welcome.tsx b/app/welcome/welcome.tsx index 970cc1e..95e319e 100644 --- a/app/welcome/welcome.tsx +++ b/app/welcome/welcome.tsx @@ -1,23 +1,10 @@ -import { Form, Link, useNavigation } from "react-router"; +import { Link } from "react-router"; import { Button } from "~/components/ui/button"; import logoDark from "./logo-dark.svg"; import logoLight from "./logo-light.svg"; -export function Welcome({ - guestBook, - guestBookError, - message, -}: { - guestBook: { - name: string; - id: number; - }[]; - guestBookError?: string; - message: string; -}) { - const navigation = useNavigation(); - +export function Welcome({ message }: { message: string }) { return (
@@ -62,55 +49,6 @@ export function Welcome({ ))} -
-
{ - if (navigation.state === "submitting") { - event.preventDefault(); - } - const form = event.currentTarget; - requestAnimationFrame(() => { - form.reset(); - }); - }} - > - - - - {guestBookError && ( -

- {guestBookError} -

- )} -
-
    - {
  • {message}
  • } - {guestBook.map(({ id, name }) => ( -
  • - {name} -
  • - ))} -
-
diff --git a/database/schema.ts b/database/schema.ts index adf29c4..50e1235 100644 --- a/database/schema.ts +++ b/database/schema.ts @@ -1,11 +1,5 @@ import { integer, pgTable, varchar, uuid, timestamp, pgEnum } from "drizzle-orm/pg-core"; -export const guestBook = pgTable("guestBook", { - id: integer().primaryKey().generatedAlwaysAsIdentity(), - name: varchar({ length: 255 }).notNull(), - email: varchar({ length: 255 }).notNull().unique(), -}); - // Users table - synced from Clerk export const users = pgTable("users", { id: uuid("id").primaryKey().defaultRandom(), diff --git a/drizzle/0005_abnormal_thunderbird.sql b/drizzle/0005_abnormal_thunderbird.sql new file mode 100644 index 0000000..556b01c --- /dev/null +++ b/drizzle/0005_abnormal_thunderbird.sql @@ -0,0 +1 @@ +DROP TABLE "guestBook" CASCADE; \ No newline at end of file diff --git a/drizzle/meta/0005_snapshot.json b/drizzle/meta/0005_snapshot.json new file mode 100644 index 0000000..c35d0d9 --- /dev/null +++ b/drizzle/meta/0005_snapshot.json @@ -0,0 +1,341 @@ +{ + "id": "6839ce43-d04c-4246-9b00-7820935e1166", + "prevId": "5e858241-1709-4099-90d2-58c7e3bf0d23", + "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 + }, + "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'" + }, + "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" + } + }, + "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 + }, + "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 + }, + "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 + }, + "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.season_status": { + "name": "season_status", + "schema": "public", + "values": [ + "pre_draft", + "draft", + "active", + "completed" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 001f81d..5063c4a 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -36,6 +36,13 @@ "when": 1760168383812, "tag": "0004_spicy_zarda", "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1760169537260, + "tag": "0005_abnormal_thunderbird", + "breakpoints": true } ] } \ No newline at end of file