Commit Graph

30 Commits

Author SHA1 Message Date
Trey t
81095a8170 fix: resolve 4 UI/planning bugs from issue tracker
- Lock all maps to North America (no pan/zoom) in ProgressMapView and TripDetailView
- Sort saved trips by most cities (stops count)
- Filter cross-country trips to top 2 by stops on home screen
- Use LocationSearchSheet for Follow Team home location (consistent with must-stop)
- Initialize DateRangePicker to show selected dates on appear

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:46:40 -06:00
Trey t
b4ac1f7c24 refactor: redesign planning mode picker as 2x2 card grid
Replace crowded segmented control with clean card-based grid.
Each card shows icon and label with selected state highlight.
Fixes text truncation issue with "Follow Team" option.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:48:58 -06:00
Trey t
f7faec01b1 feat: add Follow Team Mode (Scenario D) for road trip planning
Adds a new planning mode that lets users follow a team's schedule
(home + away games) and builds multi-city routes accordingly.

Key changes:
- New ScenarioDPlanner with team filtering and route generation
- Team picker UI with sport grouping and search
- Fix TravelEstimator 5-day limit (was 2-day) for cross-country routes
- Fix DateInterval end boundary to include games on last day
- Comprehensive test suite covering edge cases:
  - Multi-city routes with adequate/insufficient time
  - Optimal game selection per city for feasibility
  - 5-day driving segment limits
  - Multiple driver scenarios

Enables trips like Houston → Chicago → Anaheim following the Astros.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:42:43 -06:00
Trey t
5d1e9a3f48 feat: add privacy policy and terms of service
- Add HTML files for hosting at 88oakapps.com/privacy and /terms
- Update SettingsView links to use 88oakapps.com domain
- Plain English, minimal legal documents for freemium app

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:00:03 -06:00
Trey t
475f444288 refactor: extract reusable SportSelectorGrid component
Create unified sport selector grid used across Home (Quick Start),
Trip Creation, and Progress views. Removes duplicate button implementations
and ensures consistent grid layout with centered bottom row.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:38:10 -06:00
Trey t
a292b5c20c fix: center Quick Start bottom row with consistent button sizing
Use GeometryReader to calculate button width as 1/4 of available space,
ensuring all buttons have the same size. Bottom row (MLS, WNBA, NWSL)
is now centered with WNBA in the middle.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:29:14 -06:00
Trey t
2d48f1411a feat: implement Dynamic Type with Apple text styles
Replace all custom Theme.FontSize values and hardcoded font sizes with
Apple's built-in text styles (.largeTitle, .title2, .headline, .body,
.subheadline, .caption, .caption2) to support accessibility scaling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:23:16 -06:00
Trey t
284a10d9e1 feat(ui): add interactive MapKit region picker
Replace abstract colored rectangles with actual North America map
using MapKit. Regions now follow state borders with tappable
overlays for West/Central/East selection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:18:10 -06:00
Trey t
12a219d826 fix(trip): remove buffer days from trip planner
Buffer days added no value to trip planning. Itineraries now show
only game days and necessary travel days without extra padding.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:47:34 -06:00
Trey t
5ed4e309bd feat(schedule): group games by sport instead of date
Games in schedule view now display in sport sections (MLB, NBA, etc.)
with games sorted by date within each section. Each game row shows its
date since the section header now shows sport instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:36:22 -06:00
Trey t
6db0bdefcd fix(trip): redesign By Games mode with hierarchical calendar picker
Replace navigation-based team→games flow with expandable Sport→Team→Date
hierarchy. Games now grouped by date under each team with inline selection.
Also fixed game loading to always fetch 90-day browsing window.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:31:16 -06:00
Trey t
8790d2ad73 Remove CFB/NASCAR/PGA and streamline to 8 supported sports
- Remove College Football, NASCAR, and PGA from scraper and app
- Clean all data files (stadiums, games, pipeline reports)
- Update Sport.swift enum and all UI components
- Add sportstime.py CLI tool for pipeline management
- Add DATA_SCRAPING.md documentation
- Add WNBA/MLS/NWSL implementation documentation
- Scraper now supports: NBA, MLB, NHL, NFL, WNBA, MLS, NWSL, CBB

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 23:22:13 -06:00
Trey t
f5e509a9ae Add region-based filtering and route length diversity
- Add RegionMapSelector UI for geographic trip filtering (East/Central/West)
- Add RouteFilters module for allowRepeatCities preference
- Improve GameDAGRouter to preserve route length diversity
  - Routes now grouped by city count before scoring
  - Ensures 2-city trips appear alongside longer trips
  - Increased beam width and max options for better coverage
- Add TripOptionsView filters (max cities slider, pace filter)
- Remove TravelStyle section from trip creation (replaced by region selector)
- Clean up debug logging from DataProvider and ScenarioAPlanner

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 15:18:37 -06:00
Trey t
3e778473e6 Fix coast-to-coast trips and improve itinerary display
- Fix same-day different-city validation in C2C routes (no more impossible
  games like Detroit 7:30pm AND Milwaukee 8pm on the same day)
- Cap C2C trips at 14 days max with 3 middle stops, prefer shortest routes
- Add sport icon and name to game rows in trip itinerary
- Add horizontal scroll to route dots in suggested trip cards
- Allow swipe-to-dismiss on home sheet (trip planner still blocks)
- Generate travel segments for suggested trips
- Increase DAG route lookahead to 5 days for multi-day drives

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 11:42:27 -06:00
Trey t
7efcea7bd4 Add canonical ID pipeline and fix UUID consistency for CloudKit sync
- Add local canonicalization pipeline (stadiums, teams, games) that generates
  deterministic canonical IDs before CloudKit upload
- Fix CanonicalSyncService to use deterministic UUIDs from canonical IDs
  instead of random UUIDs from CloudKit records
- Add SyncStadium/SyncTeam/SyncGame types to CloudKitService that preserve
  canonical ID relationships during sync
- Add canonical ID field keys to CKModels for reading from CloudKit records
- Bundle canonical JSON files (stadiums_canonical, teams_canonical,
  games_canonical, stadium_aliases) for consistent bootstrap data
- Update BootstrapService to prefer canonical format files over legacy format

This ensures all entities use consistent deterministic UUIDs derived from
their canonical IDs, preventing duplicate records when syncing CloudKit
data with bootstrapped local data.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 10:30:09 -06:00
Trey t
588938d2a1 Add team autocomplete and themed backgrounds to Log Visit sheet
- Add autocomplete suggestions for Home/Away team fields filtered by selected sport
- Apply themed background to StadiumVisitSheet and StadiumPickerSheet
- Add listRowBackground for consistent card styling in Form sections
- Fix data observation with @ObservedObject for AppDataProvider
- Clear team names when sport selection changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 20:32:44 -06:00
Trey t
92d808caf5 Add Stadium Progress system and themed loading spinners
Stadium Progress & Achievements:
- Add StadiumVisit and Achievement SwiftData models
- Create Progress tab with interactive map view
- Implement photo-based visit import with GPS/date matching
- Add achievement badges (count-based, regional, journey)
- Create shareable progress cards for social media
- Add canonical data infrastructure (stadium identities, team aliases)
- Implement score resolution from free APIs (MLB, NBA, NHL stats)

UI Improvements:
- Add ThemedSpinner and ThemedSpinnerCompact components
- Replace all ProgressView() with themed spinners throughout app
- Fix sport selection state not persisting when navigating away

Bug Fixes:
- Fix Coast to Coast trips showing only 1 city (validation issue)
- Fix stadium progress showing 0/0 (filtering issue)
- Remove "Stadium Quest" title from progress view

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 20:20:03 -06:00
Trey t
045fcd9c07 Remove debug prints and fix build warnings
- Remove all print statements from planning engine, data providers, and PDF generation
- Fix deprecated CLGeocoder usage with MKLocalSearch for iOS 26
- Fix Swift 6 actor isolation by converting PDFGenerator/ExportService to @MainActor
- Add @retroactive to CLLocationCoordinate2D protocol conformances
- Fix unused variable warnings in GameDAGRouter and scenario planners
- Remove unreachable catch blocks in SettingsViewModel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 13:25:27 -06:00
Trey t
fbb5ae683e Enhance PDF export with maps, images, and progress UI
- Add MapSnapshotService for route maps and city maps using MKMapSnapshotter
- Add RemoteImageService for team logos and stadium photos with caching
- Add POISearchService for nearby attractions using MKLocalSearch
- Add PDFAssetPrefetcher to orchestrate parallel asset fetching
- Rewrite PDFGenerator with rich page layouts: cover, route overview,
  day-by-day itinerary, city spotlights, and summary pages
- Add export progress overlay in TripDetailView with animated progress ring

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:53:03 -06:00
Trey t
bac9cad20b Add EV charging discovery feature (disabled by flag)
- Create EVChargingService using MapKit POI search for EV chargers
- Add ItineraryBuilder.enrichWithEVChargers() for post-planning enrichment
- Update TravelSection in TripDetailView with expandable charger list
- Add FeatureFlags.enableEVCharging toggle (default: false)
- Include EVChargingFeature.md documenting API overhead

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:31:04 -06:00
Trey t
8bf8bb49cb Improve UI consistency and add heart save button
- Add themed background to all tab views (Schedule, Settings, My Trips)
- Remove navigation titles from all screens (tab bar provides context)
- Add empty state to My Trips view
- Remove max driving hours slider from trip planner (available in Settings)
- Replace save menu with heart button overlay on trip detail map
- Add ability to unsave trips by tapping heart again

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:05:28 -06:00
Trey t
415202e7f4 Add featured trips carousel on home screen
- Generate 8 suggested trips on app launch (2 per region: East, Central, West, Cross-Country)
- Each region has single-sport and multi-sport trip options
- Region classification based on stadium longitude
- Animated loading state with shimmer placeholders
- Loading messages use Foundation Models when available, fallback otherwise
- Tap card to view trip details in sheet
- Refresh button to regenerate trips
- Fixed-height cards with aligned top/bottom layout

New files:
- Region.swift: Geographic region enum with longitude classification
- LoadingTextGenerator.swift: On-device AI loading messages
- SuggestedTripsGenerator.swift: Trip generation service
- SuggestedTripCard.swift: Carousel card component
- LoadingTripsView.swift: Animated loading state

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:33:44 -06:00
Trey t
aadc82db73 Pass selected sport from quick start to trip creation
- Add initialSport parameter to TripCreationView
- Set selected sport when quick start button is tapped
- Auto-select that sport in trip planning view on appear
- Clear selection when sheet is dismissed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:54:44 -06:00
Trey t
4eca0c920c Add theme picker with 7 color schemes
- Teal: Cool cyan and teal tones (default)
- Orbit: Bold navy and orange
- Retro: Classic columbia blue
- Clutch: Championship red and gold
- Monochrome: Clean grayscale aesthetic
- Sunset: Warm oranges and purples
- Midnight: Deep blues and gold

Features:
- Theme selection persisted via UserDefaults
- ThemeManager singleton for app-wide theme state
- All Theme colors now dynamically switch based on selection
- Settings UI shows color preview circles for each theme

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:49:04 -06:00
Trey t
5bbfd30a70 Redesign trip option cards and fix various UI/planning issues
TripOptionCard improvements:
- Replace horizontal route with vertical layout (start → end with arrow)
- Remove rank badges (1, 2, 3, etc.)
- Split stats into two rows: cities/miles and sports with game counts
- Clear selection when navigating back from detail view

Settings cleanup:
- Remove unused settings (preferred game time, playoff games, notifications)
- Convert remaining settings to sliders

Planning fixes:
- Fix multi-day driving calculation in canTransition
- Remove over-restrictive trip rejection in TravelEstimator
- Clear games cache when sport selection changes

UI polish:
- RoutePreviewStrip shows all cities (abbreviated)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:05:25 -06:00
Trey t
4184af60b5 Refactor travel segments and simplify trip options
Travel segment architecture:
- Remove departureTime/arrivalTime from TravelSegment (location-based, not date-based)
- Fix travel sections appearing after destination instead of between cities
- Fix missing travel segments when revisiting same city (consecutive grouping)
- Remove unwanted rest day at end of trip

Planning engine fixes:
- All three planners now group only consecutive games at same stadium
- Visiting A → B → A creates 3 stops with proper travel between

UI simplification:
- Remove redundant sort options (mostDriving/leastDriving, mostCities/leastCities)
- Remove unused "Find Other Sports Along Route" toggle (was dead code)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 19:39:53 -06:00
Trey t
40a6f879e3 UI overhaul: new color palette, trip creation improvements, crash fix
Theme:
- New teal/cyan/mint/pink/gold color palette replacing orange/cream
- Added Theme.swift, ViewModifiers.swift, AnimatedComponents.swift

Trip Creation:
- Removed Drive/Fly toggle (drive-only for now)
- Removed Lodging Type picker
- Renamed "Number of Stops" to "Number of Cities" with explanation
- Added explanation for "Find Other Sports Along Route"
- Removed staggered animation from trip options list

Bug Fix:
- Disabled AI route description generation (Foundation Models crashes
  in iOS 26.2 Simulator due to NLLanguageRecognizer assertion failure)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 15:34:27 -06:00
Trey t
8ec8ed02b1 Refactor itinerary display: separate day sections and travel sections
- Days are now headers with games as rows in that section
- Travel between days shown in standalone "Travel" sections
- Travel timing is flexible (user decides when to drive)
- Removed complex ItineraryDay bundling approach

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 12:41:32 -06:00
Trey t
ab89c25f2f Refactor trip planning: DAG router + trip options UI + simplified itinerary
- Replace O(2^n) GeographicRouteExplorer with O(n) GameDAGRouter using DAG + beam search
- Add geographic diversity to route selection (returns routes from distinct regions)
- Add trip options selector UI (TripOptionsView, TripOptionCard) to choose between routes
- Simplify itinerary display: separate games and travel segments by date
- Remove complex ItineraryDay bundling, query games/travel directly per day
- Update ScenarioA/B/C planners to use GameDAGRouter
- Add new test suites for planners and travel estimator

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 12:26:17 -06:00
Trey t
9088b46563 Initial commit: SportsTime trip planning app
- Three-scenario planning engine (A: date range, B: selected games, C: directional routes)
- GeographicRouteExplorer with anchor game support for route exploration
- Shared ItineraryBuilder for travel segment calculation
- TravelEstimator for driving time/distance estimation
- SwiftUI views for trip creation and detail display
- CloudKit integration for schedule data
- Python scraping scripts for sports schedules

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 00:46:40 -06:00