Optimize subscription tier management and empty state logic
Changes: - Make currentTier a computed property from StoreKit instead of stored value - Initialize StoreKit at app launch and refresh on foreground for ready subscription status - Fix empty state logic: show empty state when limit > 0, upgrade prompt when limit = 0 - Add subscription status display in Profile screen (iOS/Android) - Add upgrade prompts to Residences and Tasks screens for free tier users - Improve SubscriptionHelper with better tier checking logic iOS: - SubscriptionCache: currentTier now computed from StoreKit.purchasedProductIDs - StoreKitManager: add refreshSubscriptionStatus() method - AppDelegate: initialize StoreKit at launch and refresh on app active - ContractorsListView: use shouldShowUpgradePrompt(currentCount:limitKey:) - WarrantiesTabContent/DocumentsTabContent: same empty state fix - ProfileTabView: display current tier and limitations status - ResidencesListView/ResidenceDetailView: add upgrade prompts for free users - AllTasksView: add upgrade prompt for free users Android: - ContractorsScreen/DocumentsScreen: fix empty state logic - ProfileScreen: display subscription status and limits - ResidencesScreen/ResidenceDetailScreen: add upgrade prompts - UpgradeFeatureScreen: improve UI layout Shared: - APILayer: add getSubscriptionStatus() method - SubscriptionHelper: add hasAccessToFeature() utility - Remove duplicate subscription checking logic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,9 @@ struct ResidenceDetailView: View {
|
||||
@State private var showReportConfirmation = false
|
||||
@State private var showDeleteConfirmation = false
|
||||
@State private var isDeleting = false
|
||||
|
||||
@State private var showingUpgradePrompt = false
|
||||
@StateObject private var subscriptionCache = SubscriptionCacheWrapper.shared
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
var body: some View {
|
||||
@@ -120,6 +122,9 @@ struct ResidenceDetailView: View {
|
||||
Text("Are you sure you want to archive \"\(task.title)\"? You can unarchive it later from archived tasks.")
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showingUpgradePrompt) {
|
||||
UpgradePromptView(triggerKey: "add_11th_task", isPresented: $showingUpgradePrompt)
|
||||
}
|
||||
|
||||
// MARK: onChange & lifecycle
|
||||
.onChange(of: viewModel.reportMessage) { message in
|
||||
@@ -255,7 +260,13 @@ private extension ResidenceDetailView {
|
||||
}
|
||||
|
||||
Button {
|
||||
showAddTask = true
|
||||
// Check LIVE task count before adding
|
||||
let totalTasks = tasksResponse?.columns.reduce(0) { $0 + $1.tasks.count } ?? 0
|
||||
if subscriptionCache.shouldShowUpgradePrompt(currentCount: totalTasks, limitKey: "tasks") {
|
||||
showingUpgradePrompt = true
|
||||
} else {
|
||||
showAddTask = true
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ struct ResidencesListView: View {
|
||||
@StateObject private var viewModel = ResidenceViewModel()
|
||||
@State private var showingAddResidence = false
|
||||
@State private var showingJoinResidence = false
|
||||
@State private var showingUpgradePrompt = false
|
||||
@StateObject private var authManager = AuthenticationManager.shared
|
||||
@StateObject private var subscriptionCache = SubscriptionCacheWrapper.shared
|
||||
|
||||
|
||||
var body: some View {
|
||||
@@ -71,7 +73,13 @@ struct ResidencesListView: View {
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
||||
Button(action: {
|
||||
showingJoinResidence = true
|
||||
// Check if we should show upgrade prompt before joining
|
||||
let currentCount = viewModel.myResidences?.residences.count ?? 0
|
||||
if subscriptionCache.shouldShowUpgradePrompt(currentCount: currentCount, limitKey: "properties") {
|
||||
showingUpgradePrompt = true
|
||||
} else {
|
||||
showingJoinResidence = true
|
||||
}
|
||||
}) {
|
||||
Image(systemName: "person.badge.plus")
|
||||
.font(.system(size: 18, weight: .semibold))
|
||||
@@ -79,7 +87,13 @@ struct ResidencesListView: View {
|
||||
}
|
||||
|
||||
Button(action: {
|
||||
showingAddResidence = true
|
||||
// Check if we should show upgrade prompt before adding
|
||||
let currentCount = viewModel.myResidences?.residences.count ?? 0
|
||||
if subscriptionCache.shouldShowUpgradePrompt(currentCount: currentCount, limitKey: "properties") {
|
||||
showingUpgradePrompt = true
|
||||
} else {
|
||||
showingAddResidence = true
|
||||
}
|
||||
}) {
|
||||
Image(systemName: "plus.circle.fill")
|
||||
.font(.system(size: 22, weight: .semibold))
|
||||
@@ -101,6 +115,9 @@ struct ResidencesListView: View {
|
||||
viewModel.loadMyResidences()
|
||||
})
|
||||
}
|
||||
.sheet(isPresented: $showingUpgradePrompt) {
|
||||
UpgradePromptView(triggerKey: "add_second_property", isPresented: $showingUpgradePrompt)
|
||||
}
|
||||
.onAppear {
|
||||
if authManager.isAuthenticated {
|
||||
viewModel.loadMyResidences()
|
||||
|
||||
Reference in New Issue
Block a user