Rename operator to gameday

This commit is contained in:
Codex
2026-04-22 06:58:18 -05:00
parent fe2a04343c
commit 45c2b46304
3 changed files with 16 additions and 31 deletions

View File

@@ -4,7 +4,6 @@ import { NavLink, Navigate, Route, Routes, useLocation } from "react-router-dom"
import { WalkupProvider, useWalkupContext } from "./hooks/useWalkupContext"; import { WalkupProvider, useWalkupContext } from "./hooks/useWalkupContext";
import { useSession } from "./hooks/useSession"; import { useSession } from "./hooks/useSession";
import { DashboardPage } from "./pages/DashboardPage"; import { DashboardPage } from "./pages/DashboardPage";
import { GamePage } from "./pages/GamePage";
import { LibraryPage } from "./pages/LibraryPage"; import { LibraryPage } from "./pages/LibraryPage";
import { OperatorPage } from "./pages/OperatorPage"; import { OperatorPage } from "./pages/OperatorPage";
import { ProfilePage } from "./pages/ProfilePage"; import { ProfilePage } from "./pages/ProfilePage";
@@ -18,10 +17,8 @@ function getRouteDestinationLabel(pathname: string) {
return "your dashboard"; return "your dashboard";
case "/library": case "/library":
return "walkup clips"; return "walkup clips";
case "/games":
return "game clips";
case "/operator": case "/operator":
return "the operator console"; return "gameday";
default: default:
return "this page"; return "this page";
} }
@@ -260,11 +257,8 @@ function ShellLayout() {
<NavLink to="/library" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}> <NavLink to="/library" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}>
Walkup Clips Walkup Clips
</NavLink> </NavLink>
<NavLink to="/games" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}>
Games
</NavLink>
<NavLink to="/operator" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}> <NavLink to="/operator" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}>
Operator Gameday
</NavLink> </NavLink>
<NavLink to="/profile" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}> <NavLink to="/profile" className={({ isActive }) => `nav-link${isActive ? " active" : ""}`}>
Profile Profile
@@ -281,7 +275,7 @@ function ShellLayout() {
<Route path="/profile" element={<ProtectedRoute><ProfilePage /></ProtectedRoute>} /> <Route path="/profile" element={<ProtectedRoute><ProfilePage /></ProtectedRoute>} />
<Route path="/" element={<HomeRoute />} /> <Route path="/" element={<HomeRoute />} />
<Route path="/library" element={<ProtectedRoute><TeamSelectionRoute><LibraryPage /></TeamSelectionRoute></ProtectedRoute>} /> <Route path="/library" element={<ProtectedRoute><TeamSelectionRoute><LibraryPage /></TeamSelectionRoute></ProtectedRoute>} />
<Route path="/games" element={<ProtectedRoute><TeamSelectionRoute><GamePage /></TeamSelectionRoute></ProtectedRoute>} /> <Route path="/games" element={<Navigate to="/" replace />} />
<Route path="/operator" element={<ProtectedRoute><TeamSelectionRoute><OperatorPage /></TeamSelectionRoute></ProtectedRoute>} /> <Route path="/operator" element={<ProtectedRoute><TeamSelectionRoute><OperatorPage /></TeamSelectionRoute></ProtectedRoute>} />
</Routes> </Routes>
</main> </main>

View File

@@ -38,7 +38,7 @@ export function DashboardPage() {
<div className="col-12 col-xl-6"> <div className="col-12 col-xl-6">
<div className="card shadow-sm h-100"> <div className="card shadow-sm h-100">
<div className="card-body d-grid gap-3"> <div className="card-body d-grid gap-3">
<h2 className="h4 mb-0">Next game</h2> <h2 className="h4 mb-0">Next game</h2>
{walkup.nextGame ? ( {walkup.nextGame ? (
<> <>
<strong className="fs-5">{formatGameTitle(walkup.nextGame)}</strong> <strong className="fs-5">{formatGameTitle(walkup.nextGame)}</strong>
@@ -48,13 +48,6 @@ export function DashboardPage() {
<button type="button" className="btn btn-primary" onClick={() => navigate("/library")}> <button type="button" className="btn btn-primary" onClick={() => navigate("/library")}>
Add walkup clip Add walkup clip
</button> </button>
<button
type="button"
className="btn btn-outline-secondary"
onClick={() => navigate(`/games?gameId=${encodeURIComponent(String(walkup.nextGame?.id ?? ""))}`)}
>
Attach clip to game
</button>
</div> </div>
</> </>
) : ( ) : (
@@ -66,22 +59,20 @@ export function DashboardPage() {
<div className="col-12 col-xl-6"> <div className="col-12 col-xl-6">
<div className="card shadow-sm h-100"> <div className="card shadow-sm h-100">
<div className="card-body d-grid gap-3"> <div className="card-body d-grid gap-3">
<h2 className="h4 mb-0">Other games</h2> <h2 className="h4 mb-0">Upcoming games</h2>
<div className="list-group"> <div className="list-group">
{walkup.eventsQuery.isLoading ? <div className="text-body-secondary">Loading games...</div> : null} {walkup.eventsQuery.isLoading ? <div className="text-body-secondary">Loading games...</div> : null}
{walkup.games.slice(0, 8).map((game) => ( {walkup.games.slice(0, 8).map((game) => (
<button <div
key={String(game.id)} key={String(game.id)}
type="button" className="list-group-item d-flex justify-content-between align-items-center text-start"
className="list-group-item list-group-item-action d-flex justify-content-between align-items-center text-start"
onClick={() => navigate(`/games?gameId=${encodeURIComponent(String(game.id))}`)}
> >
<div> <div>
<strong>{formatGameTitle(game)}</strong> <strong>{formatGameTitle(game)}</strong>
<div className="text-body-secondary">{formatGameDate(game)}</div> <div className="text-body-secondary">{formatGameDate(game)}</div>
</div> </div>
<span className="badge rounded-pill text-bg-warning">{String(game.id) === String(walkup.nextGame?.id) ? "Next" : "Browse"}</span> <span className="badge rounded-pill text-bg-warning">{String(game.id) === String(walkup.nextGame?.id) ? "Next" : "Browse"}</span>
</button> </div>
))} ))}
{!walkup.eventsQuery.isLoading && !walkup.games.length ? ( {!walkup.eventsQuery.isLoading && !walkup.games.length ? (
<div className="text-body-secondary">No games were returned for the selected team.</div> <div className="text-body-secondary">No games were returned for the selected team.</div>

View File

@@ -193,7 +193,7 @@ export function OperatorPage() {
const triggerAssignmentMutation = useMutation({ const triggerAssignmentMutation = useMutation({
mutationFn: (assignmentId: number) => { mutationFn: (assignmentId: number) => {
if (!playbackSessionId) { if (!playbackSessionId) {
throw new Error("Start an operator session first"); throw new Error("Start a gameday session first");
} }
return api.triggerPlaybackAssignment(selectedGameId, playbackSessionId, assignmentId); return api.triggerPlaybackAssignment(selectedGameId, playbackSessionId, assignmentId);
}, },
@@ -202,7 +202,7 @@ export function OperatorPage() {
const triggerClipMutation = useMutation({ const triggerClipMutation = useMutation({
mutationFn: (clip: AudioClip) => { mutationFn: (clip: AudioClip) => {
if (!playbackSessionId) { if (!playbackSessionId) {
throw new Error("Start an operator session first"); throw new Error("Start a gameday session first");
} }
return api.triggerPlaybackClip(selectedGameId, playbackSessionId, clip.id, selectedPlayerId); return api.triggerPlaybackClip(selectedGameId, playbackSessionId, clip.id, selectedPlayerId);
}, },
@@ -402,7 +402,7 @@ export function OperatorPage() {
if (!walkup.isTeamSnap) { if (!walkup.isTeamSnap) {
return ( return (
<section className="page-grid"> <section className="page-grid">
<div className="panel">Reconnect with TeamSnap to run operator mode.</div> <div className="panel">Reconnect with TeamSnap to run gameday mode.</div>
</section> </section>
); );
} }
@@ -412,7 +412,7 @@ export function OperatorPage() {
{isPlaybackPlaying && nowPlaying ? ( {isPlaybackPlaying && nowPlaying ? (
<div className="operator-toolbar"> <div className="operator-toolbar">
<div className="operator-toolbar-copy"> <div className="operator-toolbar-copy">
<span className="operator-toolbar-label">Now playing</span> <span className="operator-toolbar-label">Now Playing</span>
<strong>{nowPlaying.title}</strong> <strong>{nowPlaying.title}</strong>
<span className="muted">{nowPlaying.subtitle}</span> <span className="muted">{nowPlaying.subtitle}</span>
</div> </div>
@@ -427,10 +427,10 @@ export function OperatorPage() {
</div> </div>
) : null} ) : null}
<div className="hero"> <div className="hero">
<p className="eyebrow">Operator mode</p> <p className="eyebrow">Gameday mode</p>
<h1>{selectedGame ? formatGameTitle(selectedGame) : "Select a game to operate"}</h1> <h1>{selectedGame ? formatGameTitle(selectedGame) : "Select a game for gameday"}</h1>
<p> <p>
Any player can operate. The player list now follows the event lineup first, then RSVP order, and each expanded Any player can run gameday. The player list now follows the event lineup first, then RSVP order, and each expanded
row shows the current game clips before the player&apos;s library clips. row shows the current game clips before the player&apos;s library clips.
</p> </p>
</div> </div>
@@ -605,7 +605,7 @@ export function OperatorPage() {
<div className="panel stack"> <div className="panel stack">
<h2>Session</h2> <h2>Session</h2>
<button type="button" className="btn btn-primary" disabled={!selectedGameId || !teamId} onClick={() => void createSession.mutateAsync()}> <button type="button" className="btn btn-primary" disabled={!selectedGameId || !teamId} onClick={() => void createSession.mutateAsync()}>
{createSession.isPending ? "Starting..." : playbackSessionId ? "Session ready" : "Start operator session"} {createSession.isPending ? "Starting..." : playbackSessionId ? "Session ready" : "Start gameday session"}
</button> </button>
<div className="panel-note">Team: {formatTeamLabel(walkup.selectedTeam)}</div> <div className="panel-note">Team: {formatTeamLabel(walkup.selectedTeam)}</div>
<div className="panel-note">Game: {selectedGame ? formatGameDate(selectedGame) : "Select a game"}</div> <div className="panel-note">Game: {selectedGame ? formatGameDate(selectedGame) : "Select a game"}</div>