Files
FrenoCorp/Lendair/ViewModels/BeginnerModeViewModel.swift
Michael Freno 57a460761a FRE-4665: Implement Phase 3 AI training plans and premium features
- Models: TrainingPlan, Race, FamilyPlan, BeginnerMode, CommunityEvent
- Services: 5 service layers with protocol-based architecture
- ViewModels: 5 view models with @MainActor ObservableObject pattern
- Views: 10 SwiftUI views for all Phase 3 features
- Updated README with full Phase 3 documentation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-03 15:21:01 -04:00

95 lines
2.9 KiB
Swift

import Foundation
import SwiftUI
@MainActor
class BeginnerModeViewModel: ObservableObject {
@Published var config: BeginnerConfig?
@Published var milestones: [Milestone] = []
@Published var currentLevel: BeginnerLevel = .justStarted
@Published var isLoading: Bool = false
@Published var error: BeginnerModeError?
private let service: BeginnerModeServiceProtocol
init(service: BeginnerModeServiceProtocol = BeginnerModeService()) {
self.service = service
}
func fetchConfig() async {
isLoading = true
error = nil
defer { isLoading = false }
do {
config = try await service.getConfig()
currentLevel = config?.currentLevel ?? .justStarted
} catch let error as BeginnerModeError {
self.error = error
} catch {
print("Failed to fetch beginner config: \(error)")
}
}
func fetchMilestoneProgress() async {
isLoading = true
error = nil
defer { isLoading = false }
do {
let result = try await service.getMilestoneProgress()
milestones = result.milestones
currentLevel = result.level
} catch let error as BeginnerModeError {
self.error = error
} catch {
print("Failed to fetch milestone progress: \(error)")
}
}
func toggleBeginnerMode(isEnabled: Bool) async {
do {
let request = UpdateBeginnerConfigRequest(isEnabled: isEnabled)
let updatedConfig = try await service.updateConfig(request: request)
config = updatedConfig
objectWillChange.send()
} catch {
print("Failed to toggle beginner mode: \(error)")
}
}
func completeOnboardingStep(_ step: OnboardingStep) async {
guard var currentConfig = config else { return }
currentConfig.completedOnboardingSteps.append(step)
do {
let request = UpdateBeginnerConfigRequest(completedOnboardingSteps: currentConfig.completedOnboardingSteps)
let updatedConfig = try await service.updateConfig(request: request)
config = updatedConfig
objectWillChange.send()
} catch {
print("Failed to complete onboarding step: \(error)")
}
}
var onboardingSteps: [OnboardingStep] { OnboardingStep.allCases }
var completedOnboardingCount: Int {
config?.completedOnboardingSteps.count ?? 0
}
var remainingOnboardingSteps: [OnboardingStep] {
let completed = config?.completedOnboardingSteps ?? []
return onboardingSteps.filter { !completed.contains($0) }
}
var completedMilestoneCount: Int {
milestones.filter { $0.isCompleted }.count
}
var totalMilestoneCount: Int {
milestones.count
}
var levels: [BeginnerLevel] { BeginnerLevel.allCases }
}