Files
FrenoCorp/Lendair/Models/BeginnerMode.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

202 lines
5.0 KiB
Swift

import Foundation
import SwiftUI
// MARK: - Beginner Configuration
struct BeginnerConfig: Codable {
var isEnabled: Bool
var currentLevel: BeginnerLevel
var completedOnboardingSteps: [OnboardingStep]
var milestones: [Milestone]
var shownTips: Set<String>
var preferredMetric: MetricType
enum CodingKeys: String, CodingKey {
case isEnabled, currentLevel, completedOnboardingSteps, milestones, shownTips, preferredMetric
}
}
// MARK: - Beginner Level
enum BeginnerLevel: String, CaseIterable, Codable {
case justStarted
case gettingComfortable
case buildingConsistency
case progressing
var displayName: String {
switch self {
case .justStarted: return "Just Started"
case .gettingComfortable: return "Getting Comfortable"
case .buildingConsistency: return "Building Consistency"
case .progressing: return "Progressing"
}
}
var requiredWorkouts: Int {
switch self {
case .justStarted: return 0
case .gettingComfortable: return 5
case .buildingConsistency: return 15
case .progressing: return 30
}
}
var icon: String {
switch self {
case .justStarted: return "sparkles"
case .gettingComfortable: return "leaf.fill"
case .buildingConsistency: return "chart.bar.fill"
case .progressing: return "bolt.fill"
}
}
}
// MARK: - Onboarding Step
enum OnboardingStep: String, CaseIterable, Codable {
case profileSetup
case goalSelection
case firstActivity
case inviteFriends
case enableNotifications
case choosePlan
var displayName: String {
switch self {
case .profileSetup: return "Profile Setup"
case .goalSelection: return "Set Goals"
case .firstActivity: return "First Activity"
case .inviteFriends: return "Invite Friends"
case .enableNotifications: return "Enable Notifications"
case .choosePlan: return "Choose a Plan"
}
}
var description: String {
switch self {
case .profileSetup: return "Complete your profile with your name and photo"
case .goalSelection: return "Tell us what you want to achieve"
case .firstActivity: return "Record your first workout"
case .inviteFriends: return "Invite friends to join Nessa"
case .enableNotifications: return "Get reminders and updates"
case .choosePlan: return "Pick a training plan to follow"
}
}
}
// MARK: - Milestone
struct Milestone: Identifiable, Codable {
let id: String
let title: String
let description: String
let icon: String
let requirement: MilestoneRequirement
var isCompleted: Bool
var completedAt: Date?
enum CodingKeys: String, CodingKey {
case id, title, description, icon, requirement, isCompleted, completedAt
}
init(
id: String,
title: String,
description: String,
icon: String,
requirement: MilestoneRequirement,
isCompleted: Bool,
completedAt: Date?
) {
self.id = id
self.title = title
self.description = description
self.icon = icon
self.requirement = requirement
self.isCompleted = isCompleted
self.completedAt = completedAt
}
}
// MARK: - Milestone Requirement
struct MilestoneRequirement: Codable {
let type: RequirementType
let targetValue: Double
}
enum RequirementType: String, CaseIterable, Codable {
case totalDistanceKm
case totalWorkouts
case consecutiveDays
case weeklyConsistency
case firstWorkout
var displayName: String {
switch self {
case .totalDistanceKm: return "Total Distance"
case .totalWorkouts: return "Total Workouts"
case .consecutiveDays: return "Streak"
case .weeklyConsistency: return "Weekly Consistency"
case .firstWorkout: return "First Workout"
}
}
}
// MARK: - Tip
struct BeginnerTip: Identifiable, Codable {
let id: String
let context: TipContext
let title: String
let message: String
var isShown: Bool
}
enum TipContext: String, CaseIterable, Codable {
case beforeWorkout
case afterWorkout
case dailyReminder
case progressUpdate
case restDay
}
// MARK: - Metric Type
enum MetricType: String, CaseIterable, Codable {
case distance
case duration
case pace
var displayName: String {
switch self {
case .distance: return "Distance"
case .duration: return "Duration"
case .pace: return "Pace"
}
}
}
// MARK: - API Response Types
struct BeginnerConfigResponse: Decodable {
let config: BeginnerConfig
}
struct UpdateBeginnerConfigRequest: Encodable {
var isEnabled: Bool?
var completedOnboardingSteps: [OnboardingStep]?
var preferredMetric: MetricType?
}
struct UpdateBeginnerConfigResponse: Decodable {
let success: Bool
let config: BeginnerConfig
}
struct MilestoneProgressResponse: Decodable {
let milestones: [Milestone]
let currentLevel: BeginnerLevel
}