Standardize WalkUp branding
This commit is contained in:
2
PLAN.md
2
PLAN.md
@@ -1,4 +1,4 @@
|
||||
# Walkup Implementation Plan
|
||||
# WalkUp Implementation Plan
|
||||
|
||||
## Scope
|
||||
- React PWA frontend.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Walkup
|
||||
# WalkUp
|
||||
|
||||
Walkup is a collaborative baseball walk-up song app built as a React PWA with a FastAPI backend. The browser integrates with TeamSnap through the official JavaScript SDK, while the backend keeps TeamSnap secrets and only stores app-owned media and game state.
|
||||
WalkUp is a collaborative baseball walk-up song app built as a React PWA with a FastAPI backend. The browser integrates with TeamSnap through the official JavaScript SDK, while the backend keeps TeamSnap secrets and only stores app-owned media and game state.
|
||||
|
||||
## Stack
|
||||
- Frontend: React, TypeScript, Vite, React Router, TanStack Query, `teamsnap.js`, `vite-plugin-pwa`
|
||||
|
||||
@@ -9,7 +9,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
||||
|
||||
app_name: str = "Walkup API"
|
||||
app_name: str = "WalkUp API"
|
||||
backend_host: str = "0.0.0.0"
|
||||
backend_port: int = 8000
|
||||
backend_cors_origins_raw: str = "https://kif.local.ascorrea.com"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Architecture
|
||||
|
||||
Walkup is a baseball walk-up song app with a React PWA frontend and a FastAPI backend.
|
||||
WalkUp is a baseball walk-up song app with a React PWA frontend and a FastAPI backend.
|
||||
|
||||
## System Overview
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Coding Standards
|
||||
|
||||
These rules apply to Walkup-specific work in this repository.
|
||||
These rules apply to WalkUp-specific work in this repository.
|
||||
|
||||
## General
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<meta name="theme-color" content="#132238" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content="Walkup" />
|
||||
<meta name="apple-mobile-web-app-title" content="WalkUp" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
@@ -25,7 +25,7 @@
|
||||
href="/apple-splash-1290x2796.png"
|
||||
media="screen and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3)"
|
||||
/>
|
||||
<title>Walkup</title>
|
||||
<title>WalkUp</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/>
|
||||
</g>
|
||||
<text x="645" y="1848" text-anchor="middle" fill="#f4ede2" font-size="108" font-weight="700" letter-spacing="0.02em" font-family="Arial, Helvetica, sans-serif">
|
||||
Walkup
|
||||
WalkUp
|
||||
</text>
|
||||
<text x="645" y="1920" text-anchor="middle" fill="#b9c6d3" font-size="40" font-weight="500" letter-spacing="0.04em" font-family="Arial, Helvetica, sans-serif">
|
||||
Offline clip cache for the dugout
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
@@ -17,7 +17,7 @@ function getRouteDestinationLabel(pathname: string) {
|
||||
case "/":
|
||||
return "your dashboard";
|
||||
case "/library":
|
||||
return "walkup clips";
|
||||
return "WalkUp clips";
|
||||
case "/gameday":
|
||||
return "gameday";
|
||||
default:
|
||||
@@ -30,7 +30,7 @@ function getNavbarPageLabel(pathname: string) {
|
||||
case "/":
|
||||
return "Home";
|
||||
case "/library":
|
||||
return "Walkup Clips";
|
||||
return "WalkUp Clips";
|
||||
case "/gameday":
|
||||
return "Gameday";
|
||||
case "/profile":
|
||||
@@ -182,7 +182,7 @@ function TeamSelectionModal() {
|
||||
<div className="d-grid gap-2 text-body-secondary">
|
||||
<div>1. Sign in with TeamSnap.</div>
|
||||
<div>2. Choose the team you want to manage.</div>
|
||||
<div>3. Continue into the dashboard, walkup clips, or game tools.</div>
|
||||
<div>3. Continue into the dashboard, WalkUp clips, or game tools.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -204,7 +204,7 @@ class AppErrorBoundary extends Component<{ children: ReactNode }, { errorMessage
|
||||
}
|
||||
|
||||
componentDidCatch(error: unknown, errorInfo: ErrorInfo) {
|
||||
console.error("Walkup render error", error, errorInfo);
|
||||
console.error("WalkUp render error", error, errorInfo);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -266,7 +266,7 @@ function ShellLayout() {
|
||||
<i className="bi bi-person-walking" />
|
||||
</span>
|
||||
<span className="d-flex flex-column gap-0">
|
||||
<span className="fw-semibold fs-4 lh-1 text-white">Walkup</span>
|
||||
<span className="fw-semibold fs-4 lh-1 text-white">WalkUp</span>
|
||||
{currentPageLabel ? (
|
||||
<span className="navbar-text d-lg-none small lh-1 text-white-50">{currentPageLabel}</span>
|
||||
) : null}
|
||||
@@ -299,7 +299,7 @@ function ShellLayout() {
|
||||
className={`nav-link btn btn-link${location.pathname === "/library" ? " active" : ""}`}
|
||||
onClick={() => goTo("/library")}
|
||||
>
|
||||
Walkup Clips
|
||||
WalkUp Clips
|
||||
</button>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
|
||||
@@ -13,7 +13,7 @@ export function DashboardPage() {
|
||||
<div className="card shadow-sm h-100">
|
||||
<div className="card-body d-grid gap-3">
|
||||
<p className="text-uppercase small text-body-secondary mb-0">Library</p>
|
||||
<h2 className="h4 mb-0">Manage walkup clips</h2>
|
||||
<h2 className="h4 mb-0">Manage WalkUp clips</h2>
|
||||
<p className="text-body-secondary mb-0">
|
||||
Upload audio, trim clips, reorder them, and pin them to players before game day.
|
||||
</p>
|
||||
@@ -31,7 +31,7 @@ export function DashboardPage() {
|
||||
<p className="text-uppercase small text-body-secondary mb-0">Gameday</p>
|
||||
<h2 className="h4 mb-0">Run the game-day view</h2>
|
||||
<p className="text-body-secondary mb-0">
|
||||
Review lineups, check availability, and play the right walkup clips during the game.
|
||||
Review lineups, check availability, and play the right WalkUp clips during the game.
|
||||
</p>
|
||||
<div>
|
||||
<Link to="/gameday" className="btn btn-primary">
|
||||
@@ -53,7 +53,7 @@ export function DashboardPage() {
|
||||
<div className="card shadow-sm h-100">
|
||||
<div className="card-body d-grid gap-3">
|
||||
<p className="text-uppercase small text-body-secondary mb-0">Library</p>
|
||||
<h2 className="h4 mb-0">Manage walkup clips</h2>
|
||||
<h2 className="h4 mb-0">Manage WalkUp clips</h2>
|
||||
<p className="text-body-secondary mb-0">
|
||||
Upload audio, trim clips, reorder them, and pin them to players before game day.
|
||||
</p>
|
||||
@@ -71,7 +71,7 @@ export function DashboardPage() {
|
||||
<p className="text-uppercase small text-body-secondary mb-0">Gameday</p>
|
||||
<h2 className="h4 mb-0">Run the game-day view</h2>
|
||||
<p className="text-body-secondary mb-0">
|
||||
Review lineups, check availability, and play the right walkup clips during the game.
|
||||
Review lineups, check availability, and play the right WalkUp clips during the game.
|
||||
</p>
|
||||
<div>
|
||||
<Link to="/gameday" className="btn btn-primary">
|
||||
|
||||
@@ -410,11 +410,11 @@ function LibraryClips({
|
||||
});
|
||||
|
||||
if (fallbackClipsQuery.isLoading) {
|
||||
return <div className="muted">Loading walkup clips...</div>;
|
||||
return <div className="muted">Loading WalkUp clips...</div>;
|
||||
}
|
||||
|
||||
if (!fallbackClipsQuery.data?.length) {
|
||||
return <div className="muted">No walkup clips available for this player.</div>;
|
||||
return <div className="muted">No WalkUp clips available for this player.</div>;
|
||||
}
|
||||
|
||||
const clips = [...fallbackClipsQuery.data].sort((a, b) => {
|
||||
|
||||
@@ -225,7 +225,7 @@ export function LibraryPage() {
|
||||
<div className="gameday-loading-spinner spinner-border text-primary" aria-hidden="true" />
|
||||
<div className="gameday-loading-copy">
|
||||
<span className="gameday-loading-label">Waiting for TeamSnap</span>
|
||||
<strong>Loading walkup clips</strong>
|
||||
<strong>Loading WalkUp clips</strong>
|
||||
<span className="muted">Teams, roster details, and clip data are being fetched.</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -234,13 +234,13 @@ export function LibraryPage() {
|
||||
}
|
||||
|
||||
if (!walkup.isTeamSnap) {
|
||||
return <section className="page-grid"><div className="panel">Reconnect with TeamSnap to manage walkup clips.</div></section>;
|
||||
return <section className="page-grid"><div className="panel">Reconnect with TeamSnap to manage WalkUp clips.</div></section>;
|
||||
}
|
||||
|
||||
if (!teamId || !playerId) {
|
||||
return (
|
||||
<section className="page-grid">
|
||||
<div className="panel">No player record was found on the selected team, so this account cannot add walkup clips yet.</div>
|
||||
<div className="panel">No player record was found on the selected team, so this account cannot add WalkUp clips yet.</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -300,7 +300,7 @@ export function LibraryPage() {
|
||||
/>
|
||||
))}
|
||||
{!clipsQuery.isLoading && !orderedClips.length ? (
|
||||
<div className="muted">No walkup clips created yet. Open the modal to make the first one.</div>
|
||||
<div className="muted">No WalkUp clips created yet. Open the modal to make the first one.</div>
|
||||
) : null}
|
||||
{deleteClipMutation.error instanceof Error ? <div className="muted">{deleteClipMutation.error.message}</div> : null}
|
||||
</div>
|
||||
@@ -308,7 +308,7 @@ export function LibraryPage() {
|
||||
<div className="panel">
|
||||
<div className="section-header">
|
||||
<h2>Uploaded media</h2>
|
||||
<div className="muted">Review the source files behind your walkup clips. You can rename or delete uploads here.</div>
|
||||
<div className="muted">Review the source files behind your WalkUp clips. You can rename or delete uploads here.</div>
|
||||
</div>
|
||||
<div className="row walkup-panel-actions">
|
||||
<button type="button" className="btn btn-outline-secondary" onClick={openManageMedia}>
|
||||
@@ -451,7 +451,7 @@ function WalkupClipModal({
|
||||
const resolveCreatedClip = async (assetId: number) => {
|
||||
setSourceProgress({
|
||||
label: "Loading clip",
|
||||
detail: "Refreshing the library with the generated walkup clip.",
|
||||
detail: "Refreshing the library with the generated WalkUp clip.",
|
||||
percent: null,
|
||||
});
|
||||
await Promise.all([
|
||||
@@ -529,14 +529,14 @@ function WalkupClipModal({
|
||||
|
||||
setSourceProgress({
|
||||
label: "Creating clip",
|
||||
detail: "Creating a walkup clip from the selected media.",
|
||||
detail: "Creating a WalkUp clip from the selected media.",
|
||||
percent: null,
|
||||
});
|
||||
const clip = await api.createClip({
|
||||
asset_id: Number(existingAssetId),
|
||||
external_team_id: teamId,
|
||||
owner_external_player_id: playerId,
|
||||
label: draftLabel.trim() || "Walkup clip",
|
||||
label: draftLabel.trim() || "WalkUp clip",
|
||||
start_ms: 0,
|
||||
end_ms: DEFAULT_CLIP_LENGTH_MS,
|
||||
});
|
||||
@@ -548,7 +548,7 @@ function WalkupClipModal({
|
||||
setDraftClip(clip);
|
||||
setDraftStartMs(clip.start_ms);
|
||||
setDraftEndMs(clip.end_ms);
|
||||
setDraftLabel(clip.label || "Walkup clip");
|
||||
setDraftLabel(clip.label || "WalkUp clip");
|
||||
setStep("editor");
|
||||
},
|
||||
onError: () => {
|
||||
@@ -605,7 +605,7 @@ function WalkupClipModal({
|
||||
</button>
|
||||
</div>
|
||||
<div className="walkup-modal-body">
|
||||
<nav aria-label="Walkup clip steps">
|
||||
<nav aria-label="WalkUp clip steps">
|
||||
<ol className="breadcrumb walkup-step-breadcrumb mb-0">
|
||||
<li className={`breadcrumb-item${step === "source" ? " active" : ""}`} aria-current={step === "source" ? "page" : undefined}>
|
||||
Source
|
||||
@@ -618,7 +618,7 @@ function WalkupClipModal({
|
||||
|
||||
{step === "source" ? (
|
||||
<form className="stack" onSubmit={handleSourceSubmit} aria-busy={createSourceMutation.isPending}>
|
||||
<ul className="nav nav-tabs" role="tablist" aria-label="Walkup clip source">
|
||||
<ul className="nav nav-tabs" role="tablist" aria-label="WalkUp clip source">
|
||||
<li className="nav-item" role="presentation">
|
||||
<button
|
||||
id="walkup-upload-tab"
|
||||
@@ -670,7 +670,7 @@ function WalkupClipModal({
|
||||
className={`tab-pane fade${sourceMode === "upload" ? " show active" : ""}`}
|
||||
>
|
||||
<div className="stack">
|
||||
<div className="muted">Upload a local audio file to create a new walkup clip.</div>
|
||||
<div className="muted">Upload a local audio file to create a new WalkUp clip.</div>
|
||||
<label className="field">
|
||||
Media title
|
||||
<input
|
||||
@@ -732,7 +732,7 @@ function WalkupClipModal({
|
||||
className={`tab-pane fade${sourceMode === "existing" ? " show active" : ""}`}
|
||||
>
|
||||
<div className="stack">
|
||||
<div className="muted">Pick an existing media file to turn into a walkup clip.</div>
|
||||
<div className="muted">Pick an existing media file to turn into a WalkUp clip.</div>
|
||||
<label className="field">
|
||||
Existing media file
|
||||
<select
|
||||
@@ -751,7 +751,7 @@ function WalkupClipModal({
|
||||
{existingAssetId ? (
|
||||
<div className="panel-note">The clip will be created from the selected existing media file.</div>
|
||||
) : (
|
||||
<div className="muted">Choose one of the existing media files in this walkup media library.</div>
|
||||
<div className="muted">Choose one of the existing media files in this WalkUp media library.</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -878,7 +878,7 @@ function ManageUploadedMediaModal({
|
||||
>
|
||||
<div className="walkup-modal-header">
|
||||
<div>
|
||||
<p className="eyebrow mb-1">Walkup clips</p>
|
||||
<p className="eyebrow mb-1">WalkUp clips</p>
|
||||
<h2 id="walkup-media-title" className="h3 mb-0">
|
||||
Manage uploaded media
|
||||
</h2>
|
||||
@@ -894,7 +894,7 @@ function ManageUploadedMediaModal({
|
||||
</div>
|
||||
<div className="walkup-modal-body">
|
||||
<div className="panel-note">
|
||||
Rename or delete the uploaded media that backs your walkup clips. Existing clip edits stay in the clip view.
|
||||
Rename or delete the uploaded media that backs your WalkUp clips. Existing clip edits stay in the clip view.
|
||||
</div>
|
||||
<div className="stack">
|
||||
{assets.map((asset) => (
|
||||
@@ -1264,7 +1264,7 @@ function WalkupClipEditorPanel({
|
||||
mutationFn: async () => {
|
||||
const trimmedLabel = label.trim();
|
||||
if (!trimmedLabel) {
|
||||
throw new Error("Walkup clip name cannot be blank");
|
||||
throw new Error("WalkUp clip name cannot be blank");
|
||||
}
|
||||
if (endMs <= startMs) {
|
||||
throw new Error("Clip end must be greater than start");
|
||||
@@ -1312,11 +1312,11 @@ function WalkupClipEditorPanel({
|
||||
<form className="stack" onSubmit={handleSubmit}>
|
||||
<div className="panel-note">{introText}</div>
|
||||
<label className="field">
|
||||
Walkup clip name
|
||||
WalkUp clip name
|
||||
<input
|
||||
value={label}
|
||||
onChange={(event) => setLabel(event.target.value)}
|
||||
placeholder="Walkup clip name"
|
||||
placeholder="WalkUp clip name"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -30,7 +30,7 @@ export function SignInPage() {
|
||||
<div className="card shadow-sm border-0">
|
||||
<div className="card-body p-4 p-lg-5 d-grid gap-4">
|
||||
<div className="d-grid gap-2">
|
||||
<p className="text-uppercase small text-primary-emphasis mb-0">Walkup</p>
|
||||
<p className="text-uppercase small text-primary-emphasis mb-0">WalkUp</p>
|
||||
<h1 className="h2 mb-0">Sign in</h1>
|
||||
<p className="text-body-secondary mb-0">Use TeamSnap to continue into your team dashboard.</p>
|
||||
</div>
|
||||
|
||||
@@ -41,8 +41,8 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
manifest: {
|
||||
id: "/",
|
||||
name: "Walkup",
|
||||
short_name: "Walkup",
|
||||
name: "WalkUp",
|
||||
short_name: "WalkUp",
|
||||
description: "Collaborative baseball walk-up songs.",
|
||||
theme_color: "#132238",
|
||||
background_color: "#f4ede2",
|
||||
|
||||
Reference in New Issue
Block a user