refactor(wizard): show all steps at once with validation gating

- Replace progressive reveal with single fade-in of all steps
- Add canPlanTrip validation requiring all fields before planning
- Disable Plan Trip button until all selections are made
- Simplify ViewModel by removing step-by-step visibility logic
- Update tests for new validation-based approach

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-12 21:19:35 -06:00
parent 94bb68d431
commit ed526cabeb
4 changed files with 102 additions and 273 deletions

View File

@@ -2,7 +2,7 @@
// TripWizardViewModel.swift
// SportsTime
//
// ViewModel for progressive-reveal trip wizard.
// ViewModel for trip wizard.
//
import Foundation
@@ -16,7 +16,7 @@ final class TripWizardViewModel {
var planningMode: PlanningMode? = nil {
didSet {
if oldValue != nil && oldValue != planningMode {
resetDownstreamFromPlanningMode()
resetAllSelections()
}
}
}
@@ -58,49 +58,23 @@ final class TripWizardViewModel {
var sportAvailability: [Sport: Bool] = [:]
var isLoadingSportAvailability: Bool = false
// MARK: - Reveal State (computed)
// MARK: - Visibility
var isPlanningModeStepVisible: Bool { true }
var isDatesStepVisible: Bool {
/// All steps visible once planning mode is selected
var areStepsVisible: Bool {
planningMode != nil
}
var isSportsStepVisible: Bool {
isDatesStepVisible && hasSetDates
}
// MARK: - Validation
var isRegionsStepVisible: Bool {
isSportsStepVisible && !selectedSports.isEmpty
}
var isRoutePreferenceStepVisible: Bool {
isRegionsStepVisible && !selectedRegions.isEmpty
}
var isRepeatCitiesStepVisible: Bool {
isRoutePreferenceStepVisible && hasSetRoutePreference
}
var isMustStopsStepVisible: Bool {
isRepeatCitiesStepVisible && hasSetRepeatCities
}
var isReviewStepVisible: Bool {
isMustStopsStepVisible
}
/// Combined state for animation tracking
var revealState: Int {
var state = 0
if isSportsStepVisible { state += 1 }
if isDatesStepVisible { state += 2 }
if isRegionsStepVisible { state += 4 }
if isRoutePreferenceStepVisible { state += 8 }
if isRepeatCitiesStepVisible { state += 16 }
if isMustStopsStepVisible { state += 32 }
if isReviewStepVisible { state += 64 }
return state
/// All required fields must be set before planning
var canPlanTrip: Bool {
planningMode != nil &&
hasSetDates &&
!selectedSports.isEmpty &&
!selectedRegions.isEmpty &&
hasSetRoutePreference &&
hasSetRepeatCities
}
// MARK: - Sport Availability
@@ -137,7 +111,7 @@ final class TripWizardViewModel {
// MARK: - Reset Logic
private func resetDownstreamFromPlanningMode() {
private func resetAllSelections() {
selectedSports = []
hasSetDates = false
selectedRegions = []