Implement unified network layer with APILayer and migrate iOS ViewModels
Major architectural improvements: - Created APILayer as single entry point for all network operations - Integrated cache-first reads with automatic cache updates on mutations - Migrated all shared Kotlin ViewModels to use APILayer instead of direct API calls - Migrated iOS ViewModels to wrap shared Kotlin ViewModels with StateFlow observation - Replaced LookupsManager with DataCache for centralized lookup data management - Added password reset methods to AuthViewModel - Added task completion and update methods to APILayer - Added residence user management methods to APILayer iOS specific changes: - Updated LoginViewModel, RegisterViewModel, ProfileViewModel to use shared AuthViewModel - Updated ContractorViewModel, DocumentViewModel to use shared ViewModels - Updated ResidenceViewModel to use shared ViewModel and APILayer - Updated TaskViewModel to wrap shared ViewModel with callback-based interface - Migrated PasswordResetViewModel and VerifyEmailViewModel to shared AuthViewModel - Migrated AllTasksView, CompleteTaskView, EditTaskView to use APILayer - Migrated ManageUsersView, ResidenceDetailView to use APILayer - Migrated JoinResidenceView to use async/await pattern with APILayer - Removed LookupsManager.swift in favor of DataCache - Fixed PushNotificationManager @MainActor issue - Converted all direct API calls to use async/await with proper error handling Benefits: - Reduced code duplication between iOS and Android - Consistent error handling across platforms - Automatic cache management for better performance - Centralized network layer for easier testing and maintenance - Net reduction of ~700 lines of code through shared logic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import ComposeApp
|
||||
struct ContractorFormSheet: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@StateObject private var viewModel = ContractorViewModel()
|
||||
@ObservedObject private var lookupsManager = LookupsManager.shared
|
||||
|
||||
let contractor: Contractor?
|
||||
let onSave: () -> Void
|
||||
@@ -28,8 +27,11 @@ struct ContractorFormSheet: View {
|
||||
@State private var showingSpecialtyPicker = false
|
||||
@FocusState private var focusedField: Field?
|
||||
|
||||
// Lookups from DataCache
|
||||
@State private var contractorSpecialties: [ContractorSpecialty] = []
|
||||
|
||||
var specialties: [String] {
|
||||
lookupsManager.contractorSpecialties.map { $0.name }
|
||||
contractorSpecialties.map { $0.name }
|
||||
}
|
||||
|
||||
enum Field: Hashable {
|
||||
@@ -258,7 +260,7 @@ struct ContractorFormSheet: View {
|
||||
}
|
||||
.onAppear {
|
||||
loadContractorData()
|
||||
lookupsManager.loadContractorSpecialties()
|
||||
loadContractorSpecialties()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,6 +288,14 @@ struct ContractorFormSheet: View {
|
||||
isFavorite = contractor.isFavorite
|
||||
}
|
||||
|
||||
private func loadContractorSpecialties() {
|
||||
Task {
|
||||
await MainActor.run {
|
||||
self.contractorSpecialties = DataCache.shared.contractorSpecialties.value as! [ContractorSpecialty]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func saveContractor() {
|
||||
if let contractor = contractor {
|
||||
// Update existing contractor
|
||||
|
||||
Reference in New Issue
Block a user