Replace PostHog integration with AnalyticsManager architecture
Remove old PostHogAnalytics singleton and replace with guide-based two-file architecture: AnalyticsManager (singleton wrapper with super properties, session replay, opt-out, subscription funnel) and AnalyticsEvent (type-safe enum with associated values). Key changes: - New API key, self-hosted analytics endpoint - All 19 events ported to type-safe AnalyticsEvent enum - Screen tracking via AnalyticsManager.Screen enum + SwiftUI modifier - Remove all identify() calls — fully anonymous analytics - Add lifecycle hooks: flush on background, update super properties on foreground - Add privacy opt-out toggle in Settings - Subscription funnel methods ready for IAP integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -221,7 +221,11 @@ struct CompleteTaskView: View {
|
||||
onRemove: {
|
||||
withAnimation {
|
||||
selectedImages.remove(at: index)
|
||||
selectedItems.remove(at: index)
|
||||
// Camera photos don't exist in selectedItems.
|
||||
// Guard the index to avoid out-of-bounds crashes.
|
||||
if index < selectedItems.count {
|
||||
selectedItems.remove(at: index)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -333,25 +337,19 @@ struct CompleteTaskView: View {
|
||||
Task {
|
||||
for await state in completionViewModel.createCompletionState {
|
||||
await MainActor.run {
|
||||
switch state {
|
||||
case let success as ApiResultSuccess<TaskCompletionResponse>:
|
||||
if let success = state as? ApiResultSuccess<TaskCompletionResponse> {
|
||||
self.isSubmitting = false
|
||||
self.onComplete(success.data?.updatedTask) // Pass back updated task
|
||||
self.dismiss()
|
||||
case let error as ApiResultError:
|
||||
} else if let error = ApiResultBridge.error(from: state) {
|
||||
self.errorMessage = error.message
|
||||
self.showError = true
|
||||
self.isSubmitting = false
|
||||
case is ApiResultLoading:
|
||||
// Still loading, continue waiting
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Break out of loop on terminal states
|
||||
if state is ApiResultSuccess<TaskCompletionResponse> || state is ApiResultError {
|
||||
if state is ApiResultSuccess<TaskCompletionResponse> || ApiResultBridge.isError(state) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -470,4 +468,3 @@ struct ContractorPickerView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user