Files
FrenoCorp/Lendair/ViewModels/CommunityEventViewModel.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

120 lines
3.6 KiB
Swift

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 }
}