Improve subscription UI and fix trial date handling

Lock Screen:
- Add light/dark mode support with adaptive colors
- Make passcode text tappable to trigger authentication

Trial Date Fixes:
- Fix IAPManager to read firstLaunchDate directly from UserDefaults
- Add expiration date check (> Date()) before showing "expires in" text
- Show "Trial expired" when trial end date is in the past
- Disable subscription bypass in DEBUG mode for testing

Month/Year Subscribe Prompts:
- Redesign with gradient icons and compelling copy
- Add fade mask (100% at top to 0% at 50%) for content behind
- Position subscribe overlay on bottom half of screen
- Month: purple/pink theme with calendar icon
- Year: orange/pink theme with chart icon

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-24 10:54:01 -06:00
parent 745e226ecb
commit cc9f9f9427
8 changed files with 275 additions and 78 deletions

View File

@@ -66,14 +66,14 @@ struct YearView: View {
}
.scrollDisabled(iapManager.shouldShowPaywall)
.mask(
// Fade effect when paywall should show: 100% at top, 0% at bottom
// Fade effect when paywall should show: 100% at top, 0% halfway down
iapManager.shouldShowPaywall ?
AnyView(
LinearGradient(
gradient: Gradient(stops: [
.init(color: .black, location: 0),
.init(color: .black, location: 0.3),
.init(color: .clear, location: 1.0)
.init(color: .clear, location: 0.5)
]),
startPoint: .top,
endPoint: .bottom
@@ -83,26 +83,72 @@ struct YearView: View {
}
if iapManager.shouldShowPaywall {
VStack {
Spacer()
VStack(spacing: 16) {
Text("Subscribe to see your full year")
.font(.headline)
.foregroundColor(textColor)
// Premium year overview prompt - bottom half
VStack(spacing: 20) {
// Icon
ZStack {
Circle()
.fill(
LinearGradient(
colors: [.orange.opacity(0.2), .pink.opacity(0.2)],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.frame(width: 80, height: 80)
Button {
showSubscriptionStore = true
} label: {
Text(String(localized: "subscription_required_button"))
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(RoundedRectangle(cornerRadius: 10).fill(Color.pink))
}
Image(systemName: "chart.bar.xaxis")
.font(.title)
.foregroundStyle(
LinearGradient(
colors: [.orange, .pink],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
}
.padding()
// Text
VStack(spacing: 10) {
Text("See Your Year at a Glance")
.font(.title3.weight(.bold))
.foregroundColor(textColor)
.multilineTextAlignment(.center)
Text("Discover your emotional rhythm across the year. Spot trends and celebrate how far you've come.")
.font(.subheadline)
.foregroundColor(textColor.opacity(0.7))
.multilineTextAlignment(.center)
.padding(.horizontal, 24)
}
// Subscribe button
Button {
showSubscriptionStore = true
} label: {
HStack {
Image(systemName: "chart.bar.fill")
Text("Unlock Year Overview")
}
.font(.headline.weight(.bold))
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 14)
.background(
LinearGradient(
colors: [.orange, .pink],
startPoint: .leading,
endPoint: .trailing
)
)
.clipShape(RoundedRectangle(cornerRadius: 14))
}
.padding(.horizontal, 24)
}
.padding(.vertical, 24)
.frame(maxWidth: .infinity)
.background(theme.currentTheme.bg)
.frame(maxHeight: .infinity, alignment: .bottom)
} else if iapManager.shouldShowTrialWarning {
VStack {
Spacer()