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>
This commit is contained in:
Trey t
2026-01-07 19:39:53 -06:00
parent 40a6f879e3
commit 4184af60b5
29 changed files with 140675 additions and 144310 deletions

View File

@@ -193,30 +193,20 @@ struct PlanningProgressView: View {
@Environment(\.colorScheme) private var colorScheme
var body: some View {
VStack(spacing: 32) {
// Animated route illustration
AnimatedRouteGraphic()
.frame(height: 150)
.padding(.horizontal, 40)
VStack(spacing: 24) {
// Simple spinner
ProgressView()
.scaleEffect(1.5)
.tint(Theme.warmOrange)
// Current step text
Text(steps[currentStep])
.font(.system(size: 18, weight: .medium))
.font(.system(size: 16, weight: .medium))
.foregroundStyle(Theme.textSecondary(colorScheme))
.animation(.easeInOut, value: currentStep)
// Progress dots
HStack(spacing: 12) {
ForEach(0..<steps.count, id: \.self) { i in
Circle()
.fill(i <= currentStep ? Theme.warmOrange : Theme.textMuted(colorScheme).opacity(0.3))
.frame(width: i == currentStep ? 10 : 8, height: i == currentStep ? 10 : 8)
.animation(Theme.Animation.spring, value: currentStep)
}
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 60)
.padding(.vertical, 40)
.task {
await animateSteps()
}
@@ -226,7 +216,7 @@ struct PlanningProgressView: View {
while !Task.isCancelled {
try? await Task.sleep(for: .milliseconds(1500))
guard !Task.isCancelled else { break }
withAnimation(Theme.Animation.spring) {
withAnimation(.easeInOut) {
currentStep = (currentStep + 1) % steps.count
}
}