Refactor iOS forms and integrate notification API with APILayer

- Refactored ContractorFormSheet to follow SwiftUI best practices
  - Moved Field enum outside struct and renamed to ContractorFormField
  - Extracted body into computed properties for better readability
  - Replaced deprecated NavigationView with NavigationStack
  - Fixed input field contrast in light mode by adding borders
  - Fixed force cast in loadContractorSpecialties

- Refactored TaskFormView to eliminate screen flickering
  - Moved Field enum outside struct and renamed to TaskFormField
  - Fixed conditional view structure that caused flicker on load
  - Used ZStack with overlay instead of if/else for loading state
  - Changed to .task modifier for proper async initialization
  - Made loadLookups properly async and fixed force casts
  - Replaced deprecated NavigationView with NavigationStack

- Integrated PushNotificationManager with APILayer
  - Updated registerDeviceWithBackend to use APILayer.shared.registerDevice()
  - Updated updateNotificationPreferences to use APILayer
  - Updated getNotificationPreferences to use APILayer
  - Added proper error handling with try-catch pattern

- Added notification operations to APILayer
  - Added NotificationApi instance
  - Implemented registerDevice, unregisterDevice
  - Implemented getNotificationPreferences, updateNotificationPreferences
  - Implemented getNotificationHistory, markNotificationAsRead
  - Implemented markAllNotificationsAsRead, getUnreadCount
  - All methods follow consistent pattern with auth token handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-11-13 13:12:54 -06:00
parent 230eb013dd
commit 2b95c3b9c1
4 changed files with 458 additions and 349 deletions

View File

@@ -25,6 +25,7 @@ object APILayer {
private val contractorApi = ContractorApi()
private val authApi = AuthApi()
private val lookupsApi = LookupsApi()
private val notificationApi = NotificationApi()
private val prefetchManager = DataPrefetchManager.getInstance()
// ==================== Lookups Operations ====================
@@ -852,4 +853,46 @@ object APILayer {
return result
}
// ==================== Notification Operations ====================
suspend fun registerDevice(request: DeviceRegistrationRequest): ApiResult<DeviceRegistrationResponse> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.registerDevice(token, request)
}
suspend fun unregisterDevice(registrationId: String): ApiResult<Unit> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.unregisterDevice(token, registrationId)
}
suspend fun getNotificationPreferences(): ApiResult<NotificationPreference> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.getNotificationPreferences(token)
}
suspend fun updateNotificationPreferences(request: UpdateNotificationPreferencesRequest): ApiResult<NotificationPreference> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.updateNotificationPreferences(token, request)
}
suspend fun getNotificationHistory(): ApiResult<List<Notification>> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.getNotificationHistory(token)
}
suspend fun markNotificationAsRead(notificationId: Int): ApiResult<Notification> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.markNotificationAsRead(token, notificationId)
}
suspend fun markAllNotificationsAsRead(): ApiResult<Map<String, Int>> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.markAllNotificationsAsRead(token)
}
suspend fun getUnreadCount(): ApiResult<UnreadCountResponse> {
val token = TokenStorage.getToken() ?: return ApiResult.Error("Not authenticated", 401)
return notificationApi.getUnreadCount(token)
}
}