feat: add sliding window trip generation for By Games mode
Adds a trip duration stepper (2-21 days) to the By Games planning mode. When users select specific games, the planner now generates ALL possible N-day windows containing those games (e.g., 7-day trips starting on different days), finding additional games in each window to maximize route options. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,9 +66,10 @@ struct TripCreationView: View {
|
||||
datesSection
|
||||
|
||||
case .gameFirst:
|
||||
// Sports + Game Picker
|
||||
// Sports + Game Picker + Trip Duration
|
||||
sportsSection
|
||||
gameBrowserSection
|
||||
tripDurationSection
|
||||
|
||||
case .locations:
|
||||
// Locations + Sports + optional games
|
||||
@@ -512,6 +513,39 @@ struct TripCreationView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var tripDurationSection: some View {
|
||||
ThemedSection(title: "Trip Duration") {
|
||||
VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
|
||||
HStack {
|
||||
Image(systemName: "calendar.badge.clock")
|
||||
.foregroundStyle(Theme.warmOrange)
|
||||
Text("Days")
|
||||
.font(.body)
|
||||
.foregroundStyle(Theme.textPrimary(colorScheme))
|
||||
|
||||
Spacer()
|
||||
|
||||
Stepper(
|
||||
value: $viewModel.gameFirstTripDuration,
|
||||
in: 2...21,
|
||||
step: 1
|
||||
) {
|
||||
Text("\(viewModel.gameFirstTripDuration) days")
|
||||
.font(.body.monospacedDigit())
|
||||
.foregroundStyle(Theme.textPrimary(colorScheme))
|
||||
}
|
||||
}
|
||||
.padding(Theme.Spacing.md)
|
||||
.background(Theme.cardBackgroundElevated(colorScheme))
|
||||
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
||||
|
||||
Text("We'll find all possible \(viewModel.gameFirstTripDuration)-day trips that include your selected games")
|
||||
.font(.caption)
|
||||
.foregroundStyle(Theme.textSecondary(colorScheme))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var sportsSection: some View {
|
||||
ThemedSection(title: "Sports") {
|
||||
SportSelectorGrid(
|
||||
@@ -1406,6 +1440,7 @@ struct LocationSearchSheet: View {
|
||||
|
||||
enum TripSortOption: String, CaseIterable, Identifiable {
|
||||
case recommended = "Recommended"
|
||||
case mostCities = "Most Cities"
|
||||
case mostGames = "Most Games"
|
||||
case leastGames = "Least Games"
|
||||
case mostMiles = "Most Miles"
|
||||
@@ -1417,6 +1452,7 @@ enum TripSortOption: String, CaseIterable, Identifiable {
|
||||
var icon: String {
|
||||
switch self {
|
||||
case .recommended: return "star.fill"
|
||||
case .mostCities: return "mappin.and.ellipse"
|
||||
case .mostGames, .leastGames: return "sportscourt"
|
||||
case .mostMiles, .leastMiles: return "road.lanes"
|
||||
case .bestEfficiency: return "gauge.with.dots.needle.33percent"
|
||||
@@ -1514,6 +1550,8 @@ struct TripOptionsView: View {
|
||||
switch sortOption {
|
||||
case .recommended:
|
||||
return filtered
|
||||
case .mostCities:
|
||||
return filtered.sorted { $0.stops.count > $1.stops.count }
|
||||
case .mostGames:
|
||||
return filtered.sorted { $0.totalGames > $1.totalGames }
|
||||
case .leastGames:
|
||||
|
||||
Reference in New Issue
Block a user