All Stories
9-5-2-boost-display-uiReadyEpic 9.5
Story 9.5.2: Boost Display UI
Status: ready-for-dev
Tasks
- **Task 1: Create OddsBoostBadge Component** (AC: #5, #2)
- 1.1: Create `/client/src/components/ui/odds-boost-badge.tsx`
- 1.2: Add props: boost (Promotion), size (sm/md/lg), showTimer (boolean)
- 1.3: Create useCountdown hook for timer logic
- 1.4: Implement timer format: HH:MM:SS with zero-padding
- 1.5: Add gradient background: yellow-400 to orange-500
- 1.6: Display Zap icon, boost percentage, and timer
- 1.7: Add timer color logic: red if <5 min, white otherwise
- 1.8: Export component with TypeScript interface
- 1.9: Add accessibility labels (aria-label for timer)
- **Task 2: Create Promotion TypeScript Interfaces** (AC: #1)
- 2.1: Create `/client/src/types/promotions.ts`
- 2.2: Define Promotion interface with all fields
- 2.3: Define PromotionType enum (odds_boost, bonus_credit, risk_free, profit_boost)
- 2.4: Define BoostedOdds interface (original, boosted, promotionId, promotionName)
- 2.5: Define PromotionResponse interface for API responses
- 2.6: Add JSDoc documentation for all types
- 2.7: Export all interfaces and enums
- **Task 3: Create useCountdown Hook** (AC: #5)
- 3.1: Create `/client/src/hooks/use-countdown.ts`
- 3.2: Accept endDate string parameter (ISO 8601 format)
- 3.3: Calculate time difference from now to endDate
- 3.4: Return object: { hours, minutes, seconds, isExpired }
- 3.5: Update countdown every second with setInterval
- 3.6: Clean up interval on unmount
- 3.7: Handle expired state (return null or isExpired: true)
- 3.8: Add zero-padding for single-digit values
- 3.9: Memoize return value to prevent unnecessary re-renders
- **Task 4: Create BetSlipWithBoosts Component** (AC: #1, #2, #3, #4, #6)
- 4.1: Create `/client/src/components/composite/betting/bet-slip-with-boosts.tsx`
- 4.2: Add props: selections (BetSelection[]), onBoostApplied callback
- 4.3: Create state: availableBoosts, appliedBoost, boostedOdds
- 4.4: Fetch available boosts on mount and when selections change
- 4.5: Call GET `/api/v1/user/promotions/available` with bet params
- 4.6: Implement applyBoost function (toggle logic)
- 4.7: Call POST `/api/v1/user/promotions/apply-boost` on apply
- 4.8: Update boostedOdds state from API response
- 4.9: Render bet selection with original/boosted odds display
- 4.10: Render available boosts section with click handlers
- 4.11: Add "Boost Applied" indicator when boost active
- 4.12: Style applied boost with yellow-500 border and background
- 4.13: Add terms link with stopPropagation on click
- 4.14: Add loading states for boost fetch and apply
- **Task 5: Create API Client Methods** (AC: #6)
- 5.1: Locate `/client/src/lib/api/api-client.ts` (or create)
- 5.2: Add getAvailablePromotions method
- 5.3: GET `/api/v1/user/promotions/available` with query params
- 5.4: Add query params: odds, sport, market, stake
- 5.5: Add JWT token from localStorage to Authorization header
- 5.6: Add applyBoost method
- 5.7: POST `/api/v1/user/promotions/apply-boost` with body
- 5.8: Body: { promotionId, originalOdds, betId? }
- 5.9: Return BoostedOdds response from API
- 5.10: Add error handling for both methods
- **Task 6: Server Endpoint - Get Available Promotions** (AC: #1)
- 6.1: Create GET `/api/v1/user/promotions/available` endpoint
- 6.2: Add query params: odds, sport, market, stake (all optional)
- 6.3: Add JWT authentication with get_current_user dependency
- 6.4: Query promotions table for user's agent active promotions
- 6.5: Filter by current date (start_date <= now <= end_date)
- 6.6: Filter by eligibility: min/max odds, stake, sport, market
- 6.7: Check user hasn't exceeded max_per_user limit
- 6.8: Check promotion hasn't exceeded max_total_uses
- 6.9: Return list of eligible promotions
- 6.10: Add response model with Pydantic validation
- **Task 7: Server Endpoint - Apply Boost** (AC: #6)
- 7.1: Create POST `/api/v1/user/promotions/apply-boost` endpoint
- 7.2: Add request body: ApplyBoostRequest (promotionId, originalOdds, betId?)
- 7.3: Add JWT authentication with get_current_user dependency
- 7.4: Validate promotion exists and is active
- 7.5: Validate user is eligible (agent customer, limits not exceeded)
- 7.6: Calculate boosted odds using PromotionLiabilityService
- 7.7: If betId provided, update bet with boosted odds
- 7.8: Record promotion use in promotion_uses table
- 7.9: Return BoostedOdds response (original, boosted, promotionId, promotionName)
- 7.10: Add error handling (400 for validation, 404 for not found)
- **Task 8: Update Bet Slip Component** (AC: #2, #3)
- 8.1: Locate existing bet slip component (e.g., `/client/src/components/composite/betting/bet-slip.tsx`)
- 8.2: Replace with BetSlipWithBoosts component
- 8.3: OR integrate BetSlipWithBoosts into existing bet slip
- 8.4: Pass current selections to BetSlipWithBoosts
- 8.5: Handle onBoostApplied callback to update bet state
- 8.6: Update odds display logic to show original/boosted
- 8.7: Update potential payout calculation with boosted odds
- 8.8: Ensure boost is included when placing bet
- 8.9: Test integration with existing betting flow
- **Task 9: Styling and Visual Design** (AC: #2, #3)
- 9.1: Create gradient backgrounds for boost badges
- 9.2: Add strikethrough styling for original odds
- 9.3: Add highlight color (yellow-400) for boosted odds
- 9.4: Add border and background transitions for boost toggle
- 9.5: Add hover states for boost buttons
- 9.6: Add focus states for accessibility (keyboard navigation)
- 9.7: Ensure mobile responsiveness (touch targets min 44px)
- 9.8: Add loading skeletons for boost fetch
- 9.9: Add success animation on boost apply
- **Task 10: Testing & Validation** (AC: All)
- 10.1: Test boost display with multiple eligible boosts
- 10.2: Test boost display with no eligible boosts
- 10.3: Test boost toggle (apply and remove)
- 10.4: Test boosted odds calculation display
- 10.5: Test countdown timer updates every second
- 10.6: Test countdown timer at <5 minutes (red color)
- 10.7: Test terms link opens in new tab
- 10.8: Test boost applied indicator shows/hides
- 10.9: Test boost persists when placing bet
- 10.10: Test error handling (API errors, expired boosts)
- 10.11: Test accessibility (screen reader, keyboard navigation)
- 10.12: Test mobile responsiveness and touch interactions
Progress
Tasks0/10
Acceptance Criteria0
Total Tasks10