bfa8345ebf
Next.js 14+ web app in web/ directory: - Landing page: Hero, How It Works, Features, 3-tier Pricing with founder badges, Footer with email capture - Blog system: MDX-powered, /blog index + /blog/[slug] pages, reading time, Open Graph tags, JSON-LD structured data - Auth pages: /login + /signup (Supabase Auth ready) - Design system: dark theme, grade colors (A/B/C/D), BetonBLK voice - 1 seed blog post: "How to Read Line Movement Like a Sharp" - Specs for 3.2 (Scan UI), 3.3 (Bet Tracker), 3.4 (Stripe) Build passes clean: 7 static pages generated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
150 lines
6.7 KiB
Markdown
150 lines
6.7 KiB
Markdown
# Feature 3.2 — Scan UI
|
|
|
|
## Overview
|
|
The parlay scanner interface. Users input legs via a manual form builder, submit for analysis, and see color-coded grades with full reasoning. Displays scan count for free tier users, upgrade prompts at the limit.
|
|
|
|
## Dependencies
|
|
- Feature 2.1 — Parlay Scan API (`POST /api/scan/parlay`)
|
|
- Feature 3.1 — Landing Page (shared layout, auth, design system)
|
|
|
|
## Page: /scan
|
|
|
|
### Layout
|
|
```
|
|
┌─────────────────────────────────────────────┐
|
|
│ Header: BetonBLK logo + nav + scan counter │
|
|
├─────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─── Leg Builder ────────────────────────┐ │
|
|
│ │ Player: [___________] (autocomplete) │ │
|
|
│ │ Stat: [points ▼] Line: [26.5] │ │
|
|
│ │ Direction: [Over ▼] Book: [DK ▼] │ │
|
|
│ │ [+ Add Leg] │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ Legs: ┌──┐ ┌──┐ ┌──┐ │
|
|
│ │L1│ │L2│ │L3│ (removable chips) │
|
|
│ └──┘ └──┘ └──┘ │
|
|
│ │
|
|
│ [🔍 Scan Parlay] │
|
|
│ │
|
|
├─────────────────────────────────────────────┤
|
|
│ Results (after scan): │
|
|
│ │
|
|
│ ┌─ Overall ──────────────────────────────┐ │
|
|
│ │ PARLAY GRADE: [B] Confidence: 68% │ │
|
|
│ │ Correlations: 1 flag │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─ Leg 1 ────────────────────────────────┐ │
|
|
│ │ Jokic Over 26.5 pts [A] 85% │ │
|
|
│ │ Season: 26.3 | Last 10: 28.1 │ │
|
|
│ │ Home: 27.8 | vs LAL: 30.5 │ │
|
|
│ │ Kill conditions: none │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─ Leg 2 ────────────────────────────────┐ │
|
|
│ │ LeBron Over 8.5 reb [C] 52% │ │
|
|
│ │ ... │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─ Correlations ─────────────────────────┐ │
|
|
│ │ ⚠ Same game, same team: LeBron + AD │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ [📋 Save to Bet Tracker] [🔄 New Scan] │
|
|
│ │
|
|
└─────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Components
|
|
|
|
**ScanCounter** (header)
|
|
- Shows "3 of 5 scans used" for free tier
|
|
- Shows "Unlimited" for paid tiers
|
|
- Progress bar visual
|
|
|
|
**LegBuilder**
|
|
- Player input with autocomplete (calls GET /players/search on NBA stats service)
|
|
- Stat type dropdown: points, rebounds, assists, threes, blocks, steals, pra, turnovers
|
|
- Line: numeric input
|
|
- Direction: over/under toggle
|
|
- Book: DraftKings, FanDuel, BetMGM dropdown
|
|
- "Add Leg" button → adds to legs list (2-12 legs)
|
|
|
|
**LegChip**
|
|
- Compact display: "Jokic O26.5 pts DK"
|
|
- Remove button (X)
|
|
- Reorderable (nice-to-have)
|
|
|
|
**ScanButton**
|
|
- Disabled until 2+ legs added
|
|
- Loading state during API call
|
|
- Calls `POST /api/scan/parlay` with auth token
|
|
|
|
**ResultsPanel**
|
|
- Overall parlay grade card (large, color-coded)
|
|
- Individual leg cards with grade, confidence, edge, reasoning summary
|
|
- Correlation flags section with icons
|
|
- Kill conditions listed per leg
|
|
|
|
**UpgradePitch** (modal or inline)
|
|
- Appears at scan 5 (from API response `upgrade_pitch`)
|
|
- Shows personalized hook, insight, CTA
|
|
- "Subscribe" button → Stripe checkout
|
|
- "Maybe Later" dismisses
|
|
|
|
**GradeCard** (shared component from 3.1)
|
|
- Letter grade (A/B/C/D) with background color
|
|
- Confidence percentage
|
|
- Edge percentage
|
|
|
|
### State Management
|
|
```
|
|
scanState = {
|
|
legs: [], // array of leg objects
|
|
isScanning: false, // loading state
|
|
results: null, // API response
|
|
error: null, // error message
|
|
scanCount: 0, // from user profile
|
|
scansRemaining: 5, // computed
|
|
upgradePitch: null, // from API when applicable
|
|
}
|
|
```
|
|
|
|
### API Integration
|
|
```
|
|
1. Player search: GET http://localhost:8000/players/search?name=...
|
|
→ Autocomplete results (debounced, 300ms)
|
|
|
|
2. Scan: POST /api/scan/parlay
|
|
Headers: { Authorization: Bearer <jwt> }
|
|
Body: { legs: [...] }
|
|
→ Full parlay analysis response
|
|
|
|
3. Save to tracker: POST /api/bets/quickslip
|
|
→ Creates bet from scan results
|
|
```
|
|
|
|
## Acceptance Criteria
|
|
1. Leg builder allows adding 2-12 legs with all required fields
|
|
2. Player autocomplete searches as user types (debounced)
|
|
3. Scan button calls API and displays results with grades
|
|
4. Grade cards show correct colors (A=green, B=yellow, C=orange, D=red)
|
|
5. Correlation flags displayed with appropriate severity icons
|
|
6. Kill conditions listed per leg
|
|
7. Scan counter shows remaining scans for free tier
|
|
8. Upgrade pitch modal appears at scan 5 with personalized content
|
|
9. "Save to Bet Tracker" creates a bet via quickslip API
|
|
10. Error states handled: API down, invalid input, auth expired
|
|
11. Responsive: works on mobile and desktop
|
|
12. Loading states during API calls
|
|
|
|
## Test Plan
|
|
- Component tests: LegBuilder adds/removes legs correctly
|
|
- Component tests: GradeCard renders correct color per grade
|
|
- Integration: full scan flow → results displayed
|
|
- Upgrade pitch: appears at correct scan count
|
|
- Error handling: API error → user-friendly message
|
|
- Responsive: mobile leg builder usable
|