A field-ready, mobile-first Progressive Web App (PWA) designed for volunteer baseball coaches to track batting practice, record spray charts, manage cage queues, and capture digital notes without slowing down practice.
Deployed live to GitHub Pages: https://cboler.github.io/baseball-practice-helper/
-
Store data richly; ask for data sparingly
- A single tap on the interactive field coordinate surface records a complete, valid batted ball observation with normalized coordinates
$[0, 1] \times [0, 1]$ . - Quality classifications (Ground Ball, Line Drive, Fly Ball, Pop Up) and hit results (Single, Double, Triple, Home Run, Out, Foul) are entirely optional one-tap chips. If the next pitch comes fast, no extra taps are required.
- A single tap on the interactive field coordinate surface records a complete, valid batted ball observation with normalized coordinates
-
Follow the pace of practice
- Batting practice is chaotic. Players miss turns, helmets get swapped, and hitters take extra swings.
- Defaults to Manual Advance so the coach decides when to advance the hitter.
- Configurable Auto-Advance automatically rotates after a target number of balls in play (1, 3, 5, or custom).
- Queue manipulation: Instant queue reordering via up/down arrows or drag-and-drop, a dedicated Defer button to send a batter back without losing their round, and a Jump to Batter selector.
- Voice recognition player switching: Press the microphone button and say "Marcus", "Williams", or "Number 12" to set the active hitter hands-free with Web Speech API.
-
True Undo restoration
- Tapping Undo removes the last recorded observation and fully restores the prior batter and turn contact count if an automatic or manual rotation occurred.
-
Local-first, zero-account reliability
- Built on native browser
IndexedDB(practice-helper-db, schema v1). - Works 100% offline at rural ballparks with spotty cellular reception.
- Never requires accounts, passwords, or cloud logins.
- Built on native browser
-
Portable, transparent data ownership
- Canonical JSON Backup/Restore: Versioned backup and restore files with strict schema validation.
-
RFC 4180 CSV Export: Exports all recorded events, spray angles, estimated distances, and splits with spreadsheet formula injection protection (
=,+,-,@escaped). -
Roster CSV Import: Quick text or CSV import supporting
#Jersey, Name, Bats, Throws, Age, Position.
-
High-contrast ballpark palette: Deep field greens (
#113d2f), rich dirt amber (#b45309), warm paper surface (#fefcf6), and crisp high-contrast text (#0e261e) designed for sunlight readability. -
Large touch targets: All interactive buttons, chips, tabs, and field surfaces exceed the recommended
$\ge 44\text{px}$ touch target guideline. -
Full responsive ergonomics:
- Phone Portrait: Field surface up top with fixed-height controls rail, current hitter badge, and on-deck queue.
- Phone Landscape & Tablet/Desktop: Side-by-side cockpit layout with field on the left and batting controls on the right.
-
Zero horizontal overflow: Validated by automated multi-viewport Playwright tests (
phone-portrait,phone-landscape,tablet-portrait,desktop).
- PWA installability: Web App Manifest with standalone display mode, maskable icons, and service worker caching for instant offline boot.
- Framework: Angular 19 (Standalone components, reactive signals, computed state, injectables)
-
State Management:
PracticeStoresignal-based store with haptic vibration feedback (navigator.vibrate) and Web Speech API player matching -
Storage: Native IndexedDB repository (
practice-helper-db) with object stores forteams,players,sessions,events,notes, andsettings -
Field Component: Custom responsive SVG coordinate surface mapping pointer events to normalized
$[0, 1] \times [0, 1]$ coordinates, rendering foul lines, warning track, base paths, density heatmaps, and observation markers - Reporting & Analytics: Spray chart plotting, 2D density heatmap binning, pull/center/opposite distribution calculations, pitcher handedness splits (vs RHP / vs LHP), and observation editing
baseball-practice-helper/
├── public/
│ ├── icons/ # High-resolution SVGs and mark icons
│ ├── favicon.ico
│ ├── manifest.webmanifest # PWA manifest
│ └── robots.txt
├── src/
│ ├── app/
│ │ ├── core/ # Domain logic, models, storage, transfer
│ │ │ ├── domain.ts # Pure functions: rotation, undo, coords, stats
│ │ │ ├── domain.spec.ts # Domain unit tests
│ │ │ ├── models.ts # Domain interfaces & constants
│ │ │ ├── practice-store.ts # Reactive signal store & audio/speech
│ │ │ ├── repository.ts # Native IndexedDB repository
│ │ │ ├── repository.spec.ts
│ │ │ ├── transfer.ts # JSON schema validator & RFC 4180 CSV
│ │ │ └── transfer.spec.ts
│ │ ├── features/
│ │ │ ├── practice/ # Live batting practice cockpit
│ │ │ ├── reports/ # Spray charts, heatmaps, analytics & editor
│ │ │ ├── roster/ # Roster & lineup management, bulk import
│ │ │ └── settings/ # Team settings, JSON backup, CSV export
│ │ ├── home/ # First-run setup wizard & season dashboard
│ │ ├── shared/ # Reusable SVG field & file download utilities
│ │ │ ├── field.component.ts # Interactive SVG coordinate surface
│ │ │ └── files.ts # Web Share API & download fallback
│ │ ├── app.ts # App shell with practice mode detection
│ │ ├── app.html
│ │ ├── app.scss
│ │ └── app.routes.ts
│ ├── index.html
│ ├── main.ts
│ └── styles.scss # Ballpark tokens, typography, sheet styling
├── e2e/
│ └── smoke.spec.ts # Playwright end-to-end journey across 4 viewports
├── docs/
│ └── data-schema.md # Schema, coordinate math, and transfer specifications
├── playwright.config.ts # Multi-device E2E configuration
└── angular.json
- Node.js
^18.19.0 || >=20.9.0 - npm
^9.0.0 || >=10.0.0
git clone https://github.com/cboler/baseball-practice-helper.git
cd baseball-practice-helper
npm cinpm startOpen http://localhost:4200 in your browser.
Every code change is validated through automated tests and strict linting:
| Command | Description | Status |
|---|---|---|
npm run lint |
Angular & TypeScript ESLint validation | 0 errors, 0 warnings |
npm test |
37 Vitest unit tests (domain, transfer, repo, analytics, shell) | All passing |
npm run e2e |
Playwright end-to-end coach journey across 4 viewports | All passing |
npm run build |
Angular production bundle compilation | All passing |
npm run build:pages |
Production build + GitHub Pages 404.html SPA fallback |
Generated |
Run Playwright E2E tests:
npm run e2eRun Vitest unit tests:
npm test -- --watch=falseThis repository utilizes GitHub Actions to continuously deploy to GitHub Pages on every push to main.
- The workflow builds the production Angular application via
npm run build:pages. - The
scripts/prepare-pages.mjsscript copiesindex.htmlto404.htmlindist/browser/to enable client-side deep linking on GitHub Pages without HTTP 404 errors. - The built artifact is uploaded and deployed using
actions/deploy-pages.
MIT License. Open source for baseball coaches, players, and leagues everywhere.