# Frontend SBA - Strat-O-Matic Baseball Association Web App

## Overview

Vue 3 + Nuxt 3 frontend for the SBA league. Real-time game interface with WebSocket communication to backend.

**Tech Stack**: Nuxt 4.1.3, TypeScript (strict), Tailwind CSS, Pinia, Socket.io-client, Discord OAuth

## CRITICAL: Nuxt 4 Breaking Changes

**MUST READ**: `.claude/NUXT4_BREAKING_CHANGES.md`

### 1. Explicit Store Imports Required

All Pinia stores MUST be explicitly imported:

```typescript
// WRONG - will cause "useAuthStore is not defined":
const authStore = useAuthStore()

// CORRECT:
import { useAuthStore } from '~/store/auth'
const authStore = useAuthStore()
```

### 2. No `app/` Directory Allowed

**CRITICAL**: Do NOT create an `app/` directory in the frontend root. Nuxt 4 treats this as a special directory that overrides `app.vue`. If NuxtWelcome appears instead of your app, delete `app/` and rebuild.

## Project Structure

```
frontend-sba/
├── components/     # See components/CLAUDE.md for inventory
│   ├── Game/       # ScoreBoard, GameBoard, CurrentSituation, PlayByPlay
│   ├── Decisions/  # DecisionPanel, DefensiveSetup, OffensiveApproach
│   ├── Substitutions/
│   └── UI/         # ActionButton, ButtonGroup, ToggleSwitch
├── composables/    # See composables/CLAUDE.md for data flow
│   ├── useWebSocket.ts   # Connection, event handlers
│   └── useGameActions.ts # Game action wrappers
├── store/          # See store/CLAUDE.md for patterns
│   ├── auth.ts     # Discord OAuth, HttpOnly cookie auth
│   ├── game.ts     # Game state, lineups, decisions
│   └── ui.ts       # Toasts, modals
├── types/          # See types/CLAUDE.md for mappings
│   ├── game.ts     # GameState, PlayResult
│   ├── player.ts   # SbaPlayer, Lineup
│   └── websocket.ts
├── pages/
├── layouts/
├── middleware/
└── plugins/
```

## Development

> **⚠️ ALWAYS USE PROD MODE**: Run the full stack via Docker with `./start.sh prod` from the project root. Dev mode (`./start.sh dev`) has broken Discord OAuth due to cookie/CORS issues. The system isn't live yet, so always use prod for testing.

```bash
# From project root - use this for testing
./start.sh prod

# Local commands (for type checking only, not running)
npm run type-check   # Check types
npm run lint         # Lint code
```

## Configuration

### Environment Variables
Copy `.env.example` to `.env` and configure:

```bash
# API endpoints
NUXT_PUBLIC_API_URL=http://localhost:8000
NUXT_PUBLIC_WS_URL=http://localhost:8000

# Discord OAuth (public client ID - safe to expose)
NUXT_PUBLIC_DISCORD_CLIENT_ID=your-client-id
NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3000/auth/callback

# Vite dev server allowed hosts (comma-separated)
# Add your domain for external access
NUXT_ALLOWED_HOSTS=localhost,127.0.0.1
```

**Note**: `NUXT_ALLOWED_HOSTS` is read in `nuxt.config.ts` to configure Vite's `allowedHosts`. Required when accessing dev server through a reverse proxy or external domain.

### League Theme
- Primary: #1e40af (SBA Blue)
- Secondary: #dc2626 (SBA Red)

## Mobile-First Design

- **Breakpoints**: xs(375px), sm(640px), md(768px), lg(1024px)
- Touch-friendly: 44x44px minimum buttons
- Sticky scoreboard, bottom sheets for inputs

## Key Architecture Concepts

### Data Resolution Pattern
Game state contains minimal `LineupPlayerState` (lineup_id, position). Use `gameStore.findPlayerInLineup(lineupId)` to get full player data (name, headshot).

### Team Determination
- Top of inning: away bats, home fields
- Bottom of inning: home bats, away fields
- Use `gameStore.battingTeamId` / `gameStore.fieldingTeamId`

**Full details**: See subdirectory CLAUDE.md files for component inventory, data flow, store patterns, and type mappings.

## References

- **WebSocket Protocol Spec**: `../.claude/WEBSOCKET_PROTOCOL_SPEC.md` - Complete event catalog and workflow
- **Implementation Guide**: `../.claude/implementation/01-infrastructure.md`
- **Full PRD**: `../prd-web-scorecard-1.1.md`

---

**League**: SBA | **Port**: 3000 | **Last Updated**: 2025-01-19

## Current Phase

### Phase F2: Game State Display - COMPLETE (2025-01-10)
Components: ScoreBoard, GameBoard, CurrentSituation, PlayByPlay

### Phase F3: Decision Input Workflow - NEXT
Components to integrate with live backend

**See**: `.claude/implementation/NEXT_SESSION.md` for detailed plan
