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>
This commit is contained in:
119
Lendair/ViewModels/CommunityEventViewModel.swift
Normal file
119
Lendair/ViewModels/CommunityEventViewModel.swift
Normal file
@@ -0,0 +1,119 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
class CommunityEventViewModel: ObservableObject {
|
||||
@Published var events: [CommunityEvent] = []
|
||||
@Published var selectedEvent: CommunityEvent?
|
||||
@Published var participants: [EventParticipant] = []
|
||||
@Published var isLoading: Bool = false
|
||||
@Published var error: CommunityEventError?
|
||||
@Published var filter: EventFilter = EventFilter()
|
||||
|
||||
private let service: CommunityEventServiceProtocol
|
||||
|
||||
init(service: CommunityEventServiceProtocol = CommunityEventService()) {
|
||||
self.service = service
|
||||
}
|
||||
|
||||
func fetchEvents() async {
|
||||
isLoading = true
|
||||
error = nil
|
||||
defer { isLoading = false }
|
||||
|
||||
do {
|
||||
events = try await service.listEvents(filter: filter)
|
||||
} catch let error as CommunityEventError {
|
||||
self.error = error
|
||||
} catch {
|
||||
print("Failed to fetch events: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func selectEvent(id: String) async {
|
||||
isLoading = true
|
||||
error = nil
|
||||
defer { isLoading = false }
|
||||
|
||||
do {
|
||||
let result = try await service.getEvent(id: id)
|
||||
selectedEvent = result.event
|
||||
participants = result.participants
|
||||
if let index = events.firstIndex(where: { $0.id == id }) {
|
||||
events[index] = result.event
|
||||
objectWillChange.send()
|
||||
}
|
||||
} catch let error as CommunityEventError {
|
||||
self.error = error
|
||||
} catch {
|
||||
print("Failed to get event: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func createEvent(request: CreateEventRequest) async -> CommunityEvent? {
|
||||
isLoading = true
|
||||
error = nil
|
||||
defer { isLoading = false }
|
||||
|
||||
do {
|
||||
let event = try await service.createEvent(request: request)
|
||||
events.insert(event, at: 0)
|
||||
objectWillChange.send()
|
||||
return event
|
||||
} catch let error as CommunityEventError {
|
||||
self.error = error
|
||||
return nil
|
||||
} catch {
|
||||
print("Failed to create event: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func updateEvent(id: String, request: UpdateEventRequest) async {
|
||||
isLoading = true
|
||||
error = nil
|
||||
defer { isLoading = false }
|
||||
|
||||
do {
|
||||
let updatedEvent = try await service.updateEvent(id: id, request: request)
|
||||
if let index = events.firstIndex(where: { $0.id == id }) {
|
||||
events[index] = updatedEvent
|
||||
objectWillChange.send()
|
||||
}
|
||||
if selectedEvent?.id == id {
|
||||
selectedEvent = updatedEvent
|
||||
}
|
||||
} catch let error as CommunityEventError {
|
||||
self.error = error
|
||||
} catch {
|
||||
print("Failed to update event: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func RSVP(eventId: String, status: RSVPStatus) async {
|
||||
do {
|
||||
try await service.RSVP(eventId: eventId, status: status)
|
||||
if let index = events.firstIndex(where: { $0.id == eventId }) {
|
||||
events[index].rsvpStatus = status
|
||||
objectWillChange.send()
|
||||
}
|
||||
} catch {
|
||||
print("Failed to RSVP: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
var upcomingEvents: [CommunityEvent] {
|
||||
events.filter { $0.isUpcoming }.sorted { $0.startDate < $1.startDate }
|
||||
}
|
||||
|
||||
var ongoingEvents: [CommunityEvent] {
|
||||
events.filter { $0.isOngoing }
|
||||
}
|
||||
|
||||
var pastEvents: [CommunityEvent] {
|
||||
events.filter { $0.isPast }.sorted { $0.endDate > $1.endDate }
|
||||
}
|
||||
|
||||
var eventTypes: [EventType] { EventType.allCases }
|
||||
var rsvpStatuses: [RSVPStatus] { RSVPStatus.allCases }
|
||||
}
|
||||
Reference in New Issue
Block a user