From 8c5a611b4b5f2808b3f2b14aebb213ee3fa70d0a Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Tue, 14 Oct 2025 22:45:24 -0700 Subject: [PATCH] feat: add random team name generation and improve league exit flow --- app/routes/home.tsx | 4 ++ app/routes/leagues/new.tsx | 26 ++++----- app/routes/teams/$teamId.settings.tsx | 3 +- app/utils/team-names.ts | 77 +++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 app/utils/team-names.ts diff --git a/app/routes/home.tsx b/app/routes/home.tsx index 816e23b..e2dac3b 100644 --- a/app/routes/home.tsx +++ b/app/routes/home.tsx @@ -63,6 +63,10 @@ export default function Home({ loaderData }: Route.ComponentProps) { toast.success("League deleted successfully"); setSearchParams({}); } + if (searchParams.get("left") === "true") { + toast.success("You have left the league. Your team is now available."); + setSearchParams({}); + } }, [searchParams, setSearchParams]); if (!isLoggedIn) { diff --git a/app/routes/leagues/new.tsx b/app/routes/leagues/new.tsx index bb93d0a..18fc291 100644 --- a/app/routes/leagues/new.tsx +++ b/app/routes/leagues/new.tsx @@ -1,19 +1,16 @@ -import { Form, Link, redirect } from "react-router"; +import { useState } from "react"; +import { Form, redirect, Link } from "react-router"; import { getAuth } from "@clerk/react-router/server"; +import type { Route } from "./+types/new"; import { createLeague, setCurrentSeason } from "~/models/league"; -import { createSeason } from "~/models/season"; -import { createManyTeams } from "~/models/team"; import { createCommissioner } from "~/models/commissioner"; +import { createSeason } from "~/models/season"; import { linkMultipleSportsToSeason } from "~/models/season-sport"; +import { createManyTeams } from "~/models/team"; import { findActiveSeasonTemplates, findSeasonTemplateWithSportsSeasons } from "~/models/season-template"; import { findAllSportsSeasons } from "~/models/sports-season"; -import type { Route } from "./+types/new"; +import { generateUniqueTeamNames } from "~/utils/team-names"; import { Button } from "~/components/ui/button"; -import { Input } from "~/components/ui/input"; -import { Label } from "~/components/ui/label"; -import { Checkbox } from "~/components/ui/checkbox"; -import { Check } from "lucide-react"; -import { useState } from "react"; import { Card, CardContent, @@ -29,6 +26,10 @@ import { SelectValue, } from "~/components/ui/select"; import { Badge } from "~/components/ui/badge"; +import { Input } from "~/components/ui/input"; +import { Label } from "~/components/ui/label"; +import { Checkbox } from "~/components/ui/checkbox"; +import { Check } from "lucide-react"; export async function loader() { const templates = await findActiveSeasonTemplates(); @@ -116,10 +117,11 @@ export async function action(args: Route.ActionArgs) { ); } - // Create teams with placeholder names - const teams = Array.from({ length: teamCountNum }, (_, i) => ({ + // Create teams with fun random names + const teamNames = generateUniqueTeamNames(teamCountNum); + const teams = teamNames.map((name, i) => ({ seasonId: season.id, - name: `Team ${i + 1}`, + name, ownerId: i === 0 ? userId : null, // Assign first team to creator })); diff --git a/app/routes/teams/$teamId.settings.tsx b/app/routes/teams/$teamId.settings.tsx index 00f9c7f..a6e5928 100644 --- a/app/routes/teams/$teamId.settings.tsx +++ b/app/routes/teams/$teamId.settings.tsx @@ -100,8 +100,7 @@ export async function action(args: Route.ActionArgs) { if (intent === "leave") { await removeTeamOwner(teamId); - const season = await findSeasonById(team.seasonId); - return redirect(`/leagues/${season?.leagueId}?left=true`); + return redirect("/?left=true"); } return { error: "Invalid action" }; diff --git a/app/utils/team-names.ts b/app/utils/team-names.ts new file mode 100644 index 0000000..a42ff6f --- /dev/null +++ b/app/utils/team-names.ts @@ -0,0 +1,77 @@ +// Fun adjectives for team names +export const adjectives = [ + "Aggressive", "Agile", "Amazing", "Ancient", "Angry", "Anxious", "Awesome", "Awkward", + "Bold", "Brave", "Bright", "Brilliant", "Bumbling", "Busy", + "Calm", "Careful", "Careless", "Charming", "Cheerful", "Clumsy", "Confident", "Confused", "Courageous", "Crazy", "Creative", "Curious", + "Daring", "Dark", "Dazzling", "Delightful", "Determined", "Dizzy", "Dynamic", + "Eager", "Electric", "Elegant", "Energetic", "Enthusiastic", "Epic", "Excited", + "Fabulous", "Fancy", "Fantastic", "Fast", "Fearless", "Ferocious", "Fierce", "Fiery", "Flying", "Foolish", "Friendly", "Frozen", "Furious", "Fuzzy", + "Gentle", "Giant", "Gigantic", "Glorious", "Golden", "Graceful", "Grumpy", + "Happy", "Hasty", "Helpful", "Heroic", "Hilarious", "Honest", "Hungry", "Hyper", + "Icy", "Incredible", "Intelligent", "Intense", "Invisible", + "Jolly", "Joyful", "Jumpy", + "Kind", + "Lazy", "Legendary", "Lightning", "Lively", "Lonely", "Loud", "Lucky", + "Mad", "Magical", "Magnificent", "Majestic", "Marvelous", "Massive", "Mighty", "Mischievous", "Mysterious", + "Nervous", "Noble", + "Odd", "Outrageous", + "Peaceful", "Perfect", "Playful", "Powerful", "Proud", "Puzzled", + "Quick", "Quiet", + "Radiant", "Raging", "Rambunctious", "Rapid", "Reckless", "Relentless", "Remarkable", "Restless", "Roaring", "Royal", "Rusty", + "Savage", "Scary", "Shiny", "Silent", "Silly", "Sleepy", "Sly", "Smart", "Smooth", "Sneaky", "Soaring", "Speedy", "Spicy", "Spirited", "Splendid", "Spooky", "Stormy", "Strange", "Strong", "Stunning", "Super", "Swift", + "Talented", "Terrible", "Terrific", "Thundering", "Timid", "Tiny", "Tough", "Tremendous", "Tricky", + "Ultimate", "Unbeatable", "Unstoppable", + "Valiant", "Vibrant", "Vicious", "Victorious", "Vigilant", "Vigorous", + "Wacky", "Wandering", "Wild", "Wise", "Witty", "Wonderful", "Wondrous", + "Zealous", "Zesty", "Zippy" +]; + +export const pluralNouns = [ + "Aardvarks", "Albatrosses", "Alligators", "Alpacas", "Anteaters", "Antelopes", "Apes", "Armadillos", + "Badgers", "Bananas", "Bats", "Bears", "Beavers", "Bees", "Beetles", "Bison", "Bobcats", "Buffaloes", "Bulldogs", "Butterflies", + "Cacti", "Camels", "Capybaras", "Cardinals", "Caribou", "Cats", "Centipedes", "Chameleons", "Cheetahs", "Chickens", "Chipmunks", "Cobras", "Cockroaches", "Condors", "Cougars", "Cows", "Coyotes", "Crabs", "Crickets", "Crocodiles", "Crows", + "Deer", "Dinosaurs", "Dogs", "Dolphins", "Donkeys", "Doves", "Dragonflies", "Dragons", "Ducks", + "Eagles", "Eels", "Elephants", "Elks", "Emus", + "Falcons", "Ferrets", "Finches", "Fireflies", "Fish", "Flamingos", "Flies", "Foxes", "Frogs", + "Gazelles", "Geckos", "Geese", "Giraffes", "Goats", "Gophers", "Gorillas", "Grasshoppers", "Grizzlies", "Groundhogs", + "Hamsters", "Hawks", "Hedgehogs", "Herons", "Hippos", "Hornets", "Horses", "Hummingbirds", "Hyenas", + "Iguanas", "Impalas", + "Jaguars", "Jellyfish", + "Kangaroos", "Koalas", "Krakens", + "Ladybugs", "Lemurs", "Leopards", "Lions", "Lizards", "Llamas", "Lobsters", "Lynxes", + "Macaws", "Magpies", "Mammoths", "Manatees", "Mantises", "Meerkats", "Mice", "Minivans", "Moles", "Mongooses", "Monkeys", "Moose", "Mosquitoes", "Moths", "Mules", + "Narwhals", "Newts", "Nightingales", + "Octopuses", "Opossums", "Orangutans", "Orcas", "Ostriches", "Otters", "Owls", "Oxen", + "Pandas", "Panthers", "Parrots", "Peacocks", "Pelicans", "Penguins", "Phoenixes", "Pigeons", "Pigs", "Piranhas", "Platypuses", "Porcupines", "Possums", "Puffins", "Pumas", "Pythons", + "Quails", + "Rabbits", "Raccoons", "Rams", "Rats", "Ravens", "Reindeer", "Rhinos", "Roadrunners", "Robins", "Roosters", + "Salamanders", "Salmon", "Scorpions", "Seagulls", "Seahorses", "Seals", "Sharks", "Sheep", "Shrews", "Shrimp", "Skunks", "Sloths", "Slugs", "Snails", "Snakes", "Sparrows", "Spiders", "Squids", "Squirrels", "Starfish", "Stingrays", "Storks", "Swallows", "Swans", + "Tarantulas", "Tigers", "Toads", "Tortoises", "Toucans", "Trout", "Turkeys", "Turtles", + "Unicorns", + "Vipers", "Vultures", + "Walruses", "Warthogs", "Wasps", "Weasels", "Whales", "Wildcats", "Wildebeests", "Wolves", "Wombats", "Woodpeckers", "Worms", + "Yaks", + "Zebras" +]; + +/** + * Generate a random team name using an adjective and plural noun + */ +export function generateRandomTeamName(): string { + const adjective = adjectives[Math.floor(Math.random() * adjectives.length)]; + const noun = pluralNouns[Math.floor(Math.random() * pluralNouns.length)]; + return `${adjective} ${noun}`; +} + +/** + * Generate multiple unique team names + */ +export function generateUniqueTeamNames(count: number): string[] { + const names = new Set(); + + while (names.size < count) { + names.add(generateRandomTeamName()); + } + + return Array.from(names); +}