feat: add meta title to all route pages (#109)

Every route now exports a meta function so the browser title bar reflects
the current page. Static pages use fixed titles; dynamic pages pull names
from loader data with a sensible fallback (e.g. league name, sport season
name, team name).

Titles follow the pattern "Page Name - Brackt" for user-facing routes and
"Page Name - Brackt Admin" for admin routes.

Fixes #74

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Chris Parsons 2026-03-10 12:10:52 -07:00 committed by GitHub
parent cf8ac8a765
commit d784571f29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 158 additions and 0 deletions

View file

@ -1,5 +1,6 @@
import { Link } from "react-router"; import { Link } from "react-router";
import type { Route } from "./+types/admin._index"; import type { Route } from "./+types/admin._index";
import { findAllSports } from "~/models/sport"; import { findAllSports } from "~/models/sport";
import { findAllSportsSeasons } from "~/models/sports-season"; import { findAllSportsSeasons } from "~/models/sports-season";
import { findAllSeasonTemplates } from "~/models/season-template"; import { findAllSeasonTemplates } from "~/models/season-template";
@ -13,6 +14,10 @@ import {
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Trophy, Calendar, FolderKanban, ArrowRight, Camera } from "lucide-react"; import { Trophy, Calendar, FolderKanban, ArrowRight, Camera } from "lucide-react";
export function meta(): Route.MetaDescriptors {
return [{ title: "Admin - Brackt" }];
}
export async function loader() { export async function loader() {
const [sports, sportsSeasons, templates] = await Promise.all([ const [sports, sportsSeasons, templates] = await Promise.all([
findAllSports(), findAllSports(),

View file

@ -1,6 +1,7 @@
import { useState } from "react"; import { useState } from "react";
import { useFetcher } from "react-router"; import { useFetcher } from "react-router";
import type { Route } from "./+types/admin.data-sync"; import type { Route } from "./+types/admin.data-sync";
import { findAllSports } from "~/models/sport"; import { findAllSports } from "~/models/sport";
import { findAllSportsSeasons } from "~/models/sports-season"; import { findAllSportsSeasons } from "~/models/sports-season";
import { findAllSeasonTemplates } from "~/models/season-template"; import { findAllSeasonTemplates } from "~/models/season-template";
@ -28,6 +29,10 @@ import {
AlertDialogTrigger, AlertDialogTrigger,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
export function meta(): Route.MetaDescriptors {
return [{ title: "Data Sync - Brackt Admin" }];
}
export async function loader() { export async function loader() {
const [sports, sportsSeasons, templates, participantCount, evCount] = const [sports, sportsSeasons, templates, participantCount, evCount] =
await Promise.all([ await Promise.all([

View file

@ -7,6 +7,10 @@ import {
} from "~/components/ui/card"; } from "~/components/ui/card";
import { Users } from "lucide-react"; import { Users } from "lucide-react";
export function meta() {
return [{ title: "Participants - Brackt Admin" }];
}
export default function AdminParticipants() { export default function AdminParticipants() {
return ( return (
<div className="p-8"> <div className="p-8">

View file

@ -1,6 +1,7 @@
import { Form, Link } from "react-router"; import { Form, Link } from "react-router";
import { useState, useEffect, useMemo } from "react"; import { useState, useEffect, useMemo } from "react";
import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId.bracket"; import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId.bracket";
import { loader, action } from "./admin.sports-seasons.$id.events.$eventId.bracket.server"; import { loader, action } from "./admin.sports-seasons.$id.events.$eventId.bracket.server";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
@ -32,6 +33,10 @@ import {
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
import { ParticipantSelector } from "~/components/ParticipantSelector"; import { ParticipantSelector } from "~/components/ParticipantSelector";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Bracket — ${data?.event?.name ?? "Event"} - Brackt Admin` }];
}
export { loader, action }; export { loader, action };
export default function EventBracket({ export default function EventBracket({

View file

@ -1,5 +1,6 @@
import { Form, Link } from "react-router"; import { Form, Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId"; import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId";
import { loader, action } from "./admin.sports-seasons.$id.events.$eventId.server"; import { loader, action } from "./admin.sports-seasons.$id.events.$eventId.server";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
@ -31,6 +32,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { useState } from "react"; import { useState } from "react";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.event?.name ?? "Event"}${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export { loader, action }; export { loader, action };
function EditEventCard({ event }: { event: { name: string; eventDate?: string | null } }) { function EditEventCard({ event }: { event: { name: string; eventDate?: string | null } }) {

View file

@ -1,5 +1,6 @@
import { Form, Link } from "react-router"; import { Form, Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id.events"; import type { Route } from "./+types/admin.sports-seasons.$id.events";
import { loader, action } from "./admin.sports-seasons.$id.events.server"; import { loader, action } from "./admin.sports-seasons.$id.events.server";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
@ -36,6 +37,10 @@ import { format, parseISO } from "date-fns";
import { QualifyingPointsStandings } from "~/components/scoring/QualifyingPointsStandings"; import { QualifyingPointsStandings } from "~/components/scoring/QualifyingPointsStandings";
import { getEventTypeLabel } from "~/models/scoring-event"; import { getEventTypeLabel } from "~/models/scoring-event";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Events — ${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export { loader, action }; export { loader, action };
export default function SportsSeasonEvents({ export default function SportsSeasonEvents({

View file

@ -1,5 +1,6 @@
import { Link } from "react-router"; import { Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id.expected-values"; import type { Route } from "./+types/admin.sports-seasons.$id.expected-values";
import { loader } from "./admin.sports-seasons.$id.expected-values.server"; import { loader } from "./admin.sports-seasons.$id.expected-values.server";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { import {
@ -19,6 +20,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { ArrowLeft, Calculator } from "lucide-react"; import { ArrowLeft, Calculator } from "lucide-react";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Expected Values — ${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export { loader }; export { loader };
const SCORING = [100, 70, 50, 40, 25, 25, 15, 15] as const; const SCORING = [100, 70, 50, 40, 25, 25, 15, 15] as const;

View file

@ -1,5 +1,6 @@
import { Form, redirect, useLoaderData, useActionData, useNavigation } from 'react-router'; import { Form, redirect, useLoaderData, useActionData, useNavigation } from 'react-router';
import type { Route } from './+types/admin.sports-seasons.$id.futures-odds'; import type { Route } from './+types/admin.sports-seasons.$id.futures-odds';
import { findSportsSeasonById, updateSportsSeason } from '~/models/sports-season'; import { findSportsSeasonById, updateSportsSeason } from '~/models/sports-season';
import { findParticipantsBySportsSeasonId } from '~/models/participant'; import { findParticipantsBySportsSeasonId } from '~/models/participant';
import { getAllParticipantEVsForSeason, batchSaveSourceOdds, batchUpsertParticipantEVs } from '~/models/participant-expected-value'; import { getAllParticipantEVsForSeason, batchSaveSourceOdds, batchUpsertParticipantEVs } from '~/models/participant-expected-value';
@ -20,6 +21,10 @@ import {
import { useState } from 'react'; import { useState } from 'react';
import { Loader2, Info, CheckCircle2, AlertCircle } from 'lucide-react'; import { Loader2, Info, CheckCircle2, AlertCircle } from 'lucide-react';
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Futures Odds — ${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export async function loader({ params }: Route.LoaderArgs) { export async function loader({ params }: Route.LoaderArgs) {
const sportsSeasonId = params.id; const sportsSeasonId = params.id;

View file

@ -1,5 +1,6 @@
import { Form, Link } from "react-router"; import { Form, Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id.participants"; import type { Route } from "./+types/admin.sports-seasons.$id.participants";
import { findSportsSeasonById } from "~/models/sports-season"; import { findSportsSeasonById } from "~/models/sports-season";
import { import {
findParticipantsBySportsSeasonId, findParticipantsBySportsSeasonId,
@ -27,6 +28,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { Plus, Trash2, ArrowLeft } from "lucide-react"; import { Plus, Trash2, ArrowLeft } from "lucide-react";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Participants — ${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export async function loader({ params }: Route.LoaderArgs) { export async function loader({ params }: Route.LoaderArgs) {
const sportsSeason = await findSportsSeasonById(params.id); const sportsSeason = await findSportsSeasonById(params.id);

View file

@ -1,5 +1,6 @@
import { Form, Link } from "react-router"; import { Form, Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id.standings"; import type { Route } from "./+types/admin.sports-seasons.$id.standings";
import { findSportsSeasonById } from "~/models/sports-season"; import { findSportsSeasonById } from "~/models/sports-season";
import { findParticipantsBySportsSeasonId } from "~/models/participant"; import { findParticipantsBySportsSeasonId } from "~/models/participant";
import { getSeasonResults, upsertSeasonResultsBulk } from "~/models/participant-season-result"; import { getSeasonResults, upsertSeasonResultsBulk } from "~/models/participant-season-result";
@ -14,6 +15,10 @@ import {
} from "~/components/ui/card"; } from "~/components/ui/card";
import { ArrowLeft, Save, ListOrdered } from "lucide-react"; import { ArrowLeft, Save, ListOrdered } from "lucide-react";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Standings — ${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export async function loader({ params }: Route.LoaderArgs) { export async function loader({ params }: Route.LoaderArgs) {
const sportsSeason = await findSportsSeasonById(params.id); const sportsSeason = await findSportsSeasonById(params.id);
if (!sportsSeason) { if (!sportsSeason) {

View file

@ -1,5 +1,6 @@
import { Form, Link, redirect, useNavigate } from "react-router"; import { Form, Link, redirect, useNavigate } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id"; import type { Route } from "./+types/admin.sports-seasons.$id";
import { findSportsSeasonById, updateSportsSeason, deleteSportsSeason } from "~/models/sports-season"; import { findSportsSeasonById, updateSportsSeason, deleteSportsSeason } from "~/models/sports-season";
import { findParticipantsBySportsSeasonId } from "~/models/participant"; import { findParticipantsBySportsSeasonId } from "~/models/participant";
import { processSeasonStandings } from "~/models/scoring-calculator"; import { processSeasonStandings } from "~/models/scoring-calculator";
@ -39,6 +40,10 @@ import { Badge } from "~/components/ui/badge";
import { Trash2, Users, Trophy, Calculator, CheckCircle2, Zap, AlertTriangle, Loader2 } from "lucide-react"; import { Trash2, Users, Trophy, Calculator, CheckCircle2, Zap, AlertTriangle, Loader2 } from "lucide-react";
import { useState } from "react"; import { useState } from "react";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}
export async function loader({ params }: Route.LoaderArgs) { export async function loader({ params }: Route.LoaderArgs) {
const sportsSeason = await findSportsSeasonById(params.id); const sportsSeason = await findSportsSeasonById(params.id);

View file

@ -1,5 +1,6 @@
import { Form, Link, redirect } from "react-router"; import { Form, Link, redirect } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.new"; import type { Route } from "./+types/admin.sports-seasons.new";
import { createSportsSeason } from "~/models/sports-season"; import { createSportsSeason } from "~/models/sports-season";
import { findAllSports } from "~/models/sport"; import { findAllSports } from "~/models/sport";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
@ -21,6 +22,10 @@ import {
} from "~/components/ui/select"; } from "~/components/ui/select";
import { useState } from "react"; import { useState } from "react";
export function meta(): Route.MetaDescriptors {
return [{ title: "New Sports Season - Brackt Admin" }];
}
export async function loader() { export async function loader() {
const sports = await findAllSports(); const sports = await findAllSports();
return { sports }; return { sports };

View file

@ -1,5 +1,6 @@
import { Link } from "react-router"; import { Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons"; import type { Route } from "./+types/admin.sports-seasons";
import { findAllSportsSeasons } from "~/models/sports-season"; import { findAllSportsSeasons } from "~/models/sports-season";
import { import {
Card, Card,
@ -20,6 +21,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
export function meta(): Route.MetaDescriptors {
return [{ title: "Sports Seasons - Brackt Admin" }];
}
export async function loader() { export async function loader() {
const sportsSeasons = await findAllSportsSeasons(); const sportsSeasons = await findAllSportsSeasons();
// Type assertion since we know the sport and participants relations are included from the model // Type assertion since we know the sport and participants relations are included from the model

View file

@ -1,5 +1,6 @@
import { Form, Link, redirect } from "react-router"; import { Form, Link, redirect } from "react-router";
import type { Route } from "./+types/admin.sports.$id"; import type { Route } from "./+types/admin.sports.$id";
import { findSportById, updateSport } from "~/models/sport"; import { findSportById, updateSport } from "~/models/sport";
import { writeFile, mkdir } from "node:fs/promises"; import { writeFile, mkdir } from "node:fs/promises";
import { join } from "node:path"; import { join } from "node:path";
@ -22,6 +23,10 @@ import {
SelectValue, SelectValue,
} from "~/components/ui/select"; } from "~/components/ui/select";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.sport?.name ?? "Sport"} - Brackt Admin` }];
}
export async function loader({ params }: Route.LoaderArgs) { export async function loader({ params }: Route.LoaderArgs) {
const sport = await findSportById(params.id); const sport = await findSportById(params.id);

View file

@ -1,5 +1,6 @@
import { Form, Link, redirect } from "react-router"; import { Form, Link, redirect } from "react-router";
import type { Route } from "./+types/admin.sports.new"; import type { Route } from "./+types/admin.sports.new";
import { createSport } from "~/models/sport"; import { createSport } from "~/models/sport";
import { writeFile, mkdir } from "node:fs/promises"; import { writeFile, mkdir } from "node:fs/promises";
import { join } from "node:path"; import { join } from "node:path";
@ -22,6 +23,10 @@ import {
SelectValue, SelectValue,
} from "~/components/ui/select"; } from "~/components/ui/select";
export function meta(): Route.MetaDescriptors {
return [{ title: "New Sport - Brackt Admin" }];
}
export async function action({ request }: Route.ActionArgs) { export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData(); const formData = await request.formData();
const name = formData.get("name"); const name = formData.get("name");

View file

@ -1,5 +1,6 @@
import { Link } from "react-router"; import { Link } from "react-router";
import type { Route } from "./+types/admin.sports"; import type { Route } from "./+types/admin.sports";
import { findAllSportsWithActiveSeasons } from "~/models/sport"; import { findAllSportsWithActiveSeasons } from "~/models/sport";
import { import {
Card, Card,
@ -20,6 +21,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
export function meta(): Route.MetaDescriptors {
return [{ title: "Sports - Brackt Admin" }];
}
export async function loader() { export async function loader() {
const sports = await findAllSportsWithActiveSeasons(); const sports = await findAllSportsWithActiveSeasons();
return { sports }; return { sports };

View file

@ -1,6 +1,7 @@
import { useLoaderData, useActionData, Form } from "react-router"; import { useLoaderData, useActionData, Form } from "react-router";
import { redirect } from "react-router"; import { redirect } from "react-router";
import type { Route } from "./+types/admin.standings-snapshots"; import type { Route } from "./+types/admin.standings-snapshots";
import { database } from "~/database/context"; import { database } from "~/database/context";
import { eq, or } from "drizzle-orm"; import { eq, or } from "drizzle-orm";
import * as schema from "~/database/schema"; import * as schema from "~/database/schema";
@ -24,6 +25,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { Calendar, RefreshCw, CheckCircle2, AlertCircle } from "lucide-react"; import { Calendar, RefreshCw, CheckCircle2, AlertCircle } from "lucide-react";
export function meta(): Route.MetaDescriptors {
return [{ title: "Standings Snapshots - Brackt Admin" }];
}
export async function loader() { export async function loader() {
const db = database(); const db = database();

View file

@ -1,6 +1,7 @@
import { Form, Link, redirect } from "react-router"; import { Form, Link, redirect } from "react-router";
import { useState } from "react"; import { useState } from "react";
import type { Route } from "./+types/admin.templates.$id"; import type { Route } from "./+types/admin.templates.$id";
import { import {
findSeasonTemplateWithSportsSeasons, findSeasonTemplateWithSportsSeasons,
updateSeasonTemplate, updateSeasonTemplate,
@ -44,6 +45,10 @@ import {
import { Trash2, Plus, X } from "lucide-react"; import { Trash2, Plus, X } from "lucide-react";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.template?.name ?? "Template"} - Brackt Admin` }];
}
export async function loader({ params }: Route.LoaderArgs) { export async function loader({ params }: Route.LoaderArgs) {
const template = await findSeasonTemplateWithSportsSeasons(params.id); const template = await findSeasonTemplateWithSportsSeasons(params.id);

View file

@ -1,5 +1,6 @@
import { Form, Link, redirect } from "react-router"; import { Form, Link, redirect } from "react-router";
import type { Route } from "./+types/admin.templates.new"; import type { Route } from "./+types/admin.templates.new";
import { createSeasonTemplate } from "~/models/season-template"; import { createSeasonTemplate } from "~/models/season-template";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
@ -13,6 +14,10 @@ import {
CardTitle, CardTitle,
} from "~/components/ui/card"; } from "~/components/ui/card";
export function meta(): Route.MetaDescriptors {
return [{ title: "New Template - Brackt Admin" }];
}
export async function action({ request }: Route.ActionArgs) { export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData(); const formData = await request.formData();
const name = formData.get("name"); const name = formData.get("name");

View file

@ -1,5 +1,6 @@
import { Link } from "react-router"; import { Link } from "react-router";
import type { Route } from "./+types/admin.templates"; import type { Route } from "./+types/admin.templates";
import { findAllSeasonTemplates } from "~/models/season-template"; import { findAllSeasonTemplates } from "~/models/season-template";
import { import {
Card, Card,
@ -20,6 +21,10 @@ import {
} from "~/components/ui/table"; } from "~/components/ui/table";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
export function meta(): Route.MetaDescriptors {
return [{ title: "Templates - Brackt Admin" }];
}
export async function loader() { export async function loader() {
const templates = await findAllSeasonTemplates(); const templates = await findAllSeasonTemplates();
return { templates }; return { templates };

View file

@ -1,6 +1,7 @@
import { Link, Outlet, redirect } from "react-router"; import { Link, Outlet, redirect } from "react-router";
import { getAuth } from "@clerk/react-router/server"; import { getAuth } from "@clerk/react-router/server";
import type { Route } from "./+types/admin"; import type { Route } from "./+types/admin";
import { isUserAdminByClerkId } from "~/models/user"; import { isUserAdminByClerkId } from "~/models/user";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { import {
@ -11,6 +12,10 @@ import {
RefreshCw, RefreshCw,
} from "lucide-react"; } from "lucide-react";
export function meta(): Route.MetaDescriptors {
return [{ title: "Admin - Brackt" }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
const { userId } = await getAuth(args); const { userId } = await getAuth(args);

View file

@ -2,6 +2,7 @@ import { Form, redirect } from "react-router";
import { getAuth } from "@clerk/react-router/server"; import { getAuth } from "@clerk/react-router/server";
import { SignInButton } from "@clerk/react-router"; import { SignInButton } from "@clerk/react-router";
import type { Route } from "./+types/i.$inviteCode"; import type { Route } from "./+types/i.$inviteCode";
import { import {
findSeasonByInviteCode, findSeasonByInviteCode,
findLeagueById, findLeagueById,
@ -19,6 +20,10 @@ import {
CardTitle, CardTitle,
} from "~/components/ui/card"; } from "~/components/ui/card";
export function meta(): Route.MetaDescriptors {
return [{ title: "Join League - Brackt" }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
const { params } = args; const { params } = args;
const { inviteCode } = params; const { inviteCode } = params;

View file

@ -9,6 +9,10 @@ import { useState, useEffect } from "react";
import { buildOwnerMap } from "~/lib/owner-map"; import { buildOwnerMap } from "~/lib/owner-map";
import type { Route } from "./+types/$leagueId.draft-board.$seasonId"; import type { Route } from "./+types/$leagueId.draft-board.$seasonId";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Draft Board — ${data?.season?.league?.name ?? "League"} - Brackt` }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
const { params } = args; const { params } = args;
const { leagueId, seasonId } = params; const { leagueId, seasonId } = params;

View file

@ -34,6 +34,10 @@ import { formatClockTime, getTimerColorClass } from "~/lib/draft-timer";
import { Users, LayoutGrid, ListChecks, Settings, ListOrdered } from "lucide-react"; import { Users, LayoutGrid, ListChecks, Settings, ListOrdered } from "lucide-react";
import type { Route } from "./+types/$leagueId.draft.$seasonId"; import type { Route } from "./+types/$leagueId.draft.$seasonId";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Draft — ${data?.season?.league?.name ?? "League"} - Brackt` }];
}
type QueueItem = typeof schema.draftQueue.$inferSelect; type QueueItem = typeof schema.draftQueue.$inferSelect;
type AutodraftStatusEntry = { type AutodraftStatusEntry = {

View file

@ -63,6 +63,10 @@ import {
import { ScoringRulesEditor } from "~/components/scoring/ScoringRulesEditor"; import { ScoringRulesEditor } from "~/components/scoring/ScoringRulesEditor";
import { toast } from "sonner"; import { toast } from "sonner";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Settings — ${data?.league?.name ?? "League"} - Brackt` }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
const { userId } = await getAuth(args); const { userId } = await getAuth(args);
const { params } = args; const { params } = args;

View file

@ -1,5 +1,6 @@
import { Link } from "react-router"; import { Link } from "react-router";
import type { Route } from "./+types/$leagueId.sports-seasons.$sportsSeasonId"; import type { Route } from "./+types/$leagueId.sports-seasons.$sportsSeasonId";
import { loader } from "./$leagueId.sports-seasons.$sportsSeasonId.server"; import { loader } from "./$leagueId.sports-seasons.$sportsSeasonId.server";
import { SportSeasonDisplay } from "~/components/scoring/SportSeasonDisplay"; import { SportSeasonDisplay } from "~/components/scoring/SportSeasonDisplay";
import { EventSchedule } from "~/components/sport-season/EventSchedule"; import { EventSchedule } from "~/components/sport-season/EventSchedule";
@ -7,6 +8,10 @@ import { Button } from "~/components/ui/button";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
import { ArrowLeft, CheckCircle2, Clock, Zap } from "lucide-react"; import { ArrowLeft, CheckCircle2, Clock, Zap } from "lucide-react";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.sportsSeason?.name ?? "Sport Season"}${data?.league?.name ?? "League"} - Brackt` }];
}
export { loader }; export { loader };
function getStatusBadge(status: string) { function getStatusBadge(status: string) {

View file

@ -1,8 +1,13 @@
import { useLoaderData } from "react-router"; import { useLoaderData } from "react-router";
import type { Route } from "./+types/$leagueId.standings.$seasonId.teams.$teamId"; import type { Route } from "./+types/$leagueId.standings.$seasonId.teams.$teamId";
import { TeamScoreBreakdown } from "~/components/standings/TeamScoreBreakdown"; import { TeamScoreBreakdown } from "~/components/standings/TeamScoreBreakdown";
import { getTeamScoreBreakdown, getTeamStanding } from "~/models/standings"; import { getTeamScoreBreakdown, getTeamStanding } from "~/models/standings";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.breakdown?.team?.name ?? "Team"} - Brackt` }];
}
/** /**
* Team score breakdown page * Team score breakdown page
* Shows all drafted participants with their placements and points * Shows all drafted participants with their placements and points

View file

@ -11,6 +11,10 @@ import { isSeasonComplete, getSeasonCompletionPercentage } from "~/lib/season-he
import { PointProgressionChart } from "~/components/standings/PointProgressionChart"; import { PointProgressionChart } from "~/components/standings/PointProgressionChart";
import type { Route } from "./+types/$leagueId.standings.$seasonId"; import type { Route } from "./+types/$leagueId.standings.$seasonId";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Standings — ${data?.league?.name ?? "League"} - Brackt` }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
try { try {
const { userId } = await getAuth(args); const { userId } = await getAuth(args);

View file

@ -3,6 +3,7 @@ import { Link, useSearchParams } from "react-router";
import { toast } from "sonner"; import { toast } from "sonner";
import { format } from "date-fns"; import { format } from "date-fns";
import type { Route } from "./+types/$leagueId"; import type { Route } from "./+types/$leagueId";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { import {
Card, Card,
@ -14,6 +15,10 @@ import {
import { SportSeasonCard } from "~/components/sports/SportSeasonCard"; import { SportSeasonCard } from "~/components/sports/SportSeasonCard";
import { getDisplayRank } from "~/lib/standings-display"; import { getDisplayRank } from "~/lib/standings-display";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `${data?.league?.name ?? "League"} - Brackt` }];
}
export { loader } from "./$leagueId.server"; export { loader } from "./$leagueId.server";
export default function LeagueHome({ loaderData }: Route.ComponentProps) { export default function LeagueHome({ loaderData }: Route.ComponentProps) {

View file

@ -2,6 +2,7 @@ import { useState } from "react";
import { Form, redirect, Link } from "react-router"; import { Form, redirect, Link } from "react-router";
import { getAuth } from "@clerk/react-router/server"; import { getAuth } from "@clerk/react-router/server";
import type { Route } from "./+types/new"; import type { Route } from "./+types/new";
import { createLeague, setCurrentSeason } from "~/models/league"; import { createLeague, setCurrentSeason } from "~/models/league";
import { createCommissioner } from "~/models/commissioner"; import { createCommissioner } from "~/models/commissioner";
import { createSeason } from "~/models/season"; import { createSeason } from "~/models/season";
@ -40,6 +41,10 @@ import {
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { ScoringRulesEditor } from "~/components/scoring/ScoringRulesEditor"; import { ScoringRulesEditor } from "~/components/scoring/ScoringRulesEditor";
export function meta(): Route.MetaDescriptors {
return [{ title: "New League - Brackt" }];
}
export async function loader() { export async function loader() {
const templates = await findActiveSeasonTemplates(); const templates = await findActiveSeasonTemplates();
const allSportsSeasons = await findAllSportsSeasons(); const allSportsSeasons = await findAllSportsSeasons();

View file

@ -1,6 +1,7 @@
import { Form, redirect, useNavigate } from "react-router"; import { Form, redirect, useNavigate } from "react-router";
import { getAuth } from "@clerk/react-router/server"; import { getAuth } from "@clerk/react-router/server";
import type { Route } from "./+types/$teamId.settings"; import type { Route } from "./+types/$teamId.settings";
import { import {
findTeamById, findTeamById,
updateTeam, updateTeam,
@ -29,6 +30,10 @@ import {
AlertDialogTrigger, AlertDialogTrigger,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
return [{ title: `Team Settings — ${data?.team?.name ?? "Team"} - Brackt` }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
const { params } = args; const { params } = args;
const { teamId } = params; const { teamId } = params;

View file

@ -1,6 +1,10 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { useDraftSocket } from "~/hooks/useDraftSocket"; import { useDraftSocket } from "~/hooks/useDraftSocket";
export function meta() {
return [{ title: "Socket Test - Brackt" }];
}
export default function TestSocket() { export default function TestSocket() {
const [messages, setMessages] = useState<string[]>([]); const [messages, setMessages] = useState<string[]>([]);
const { isConnected, on, off, emit } = useDraftSocket("test-season-123"); const { isConnected, on, off, emit } = useDraftSocket("test-season-123");

View file

@ -3,6 +3,10 @@ import { getAuth } from "@clerk/react-router/server";
import { redirect } from "react-router"; import { redirect } from "react-router";
import type { Route } from "./+types/user-profile"; import type { Route } from "./+types/user-profile";
export function meta(): Route.MetaDescriptors {
return [{ title: "Profile - Brackt" }];
}
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
const { userId } = await getAuth(args); const { userId } = await getAuth(args);