Primera build enviada
This commit is contained in:
@@ -89,6 +89,9 @@ struct DashboardView: View {
|
||||
.sheet(isPresented: $showingCustomize) {
|
||||
DashboardCustomizeView(configs: $sectionConfigs)
|
||||
}
|
||||
.sheet(isPresented: $viewModel.showingPaywall) {
|
||||
PaywallView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +110,13 @@ struct DashboardView: View {
|
||||
|
||||
Divider()
|
||||
|
||||
ForEach(accountStore.accounts) { account in
|
||||
ForEach(availableAccounts, id: \.objectID) { account in
|
||||
Button {
|
||||
accountStore.selectAccount(account)
|
||||
} label: {
|
||||
HStack {
|
||||
Text(account.name)
|
||||
if accountStore.selectedAccount?.id == account.id && !accountStore.showAllAccounts {
|
||||
if accountStore.selectedAccount?.safeId == account.safeId && !accountStore.showAllAccounts {
|
||||
Image(systemName: "checkmark")
|
||||
}
|
||||
}
|
||||
@@ -124,6 +127,10 @@ struct DashboardView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var availableAccounts: [Account] {
|
||||
accountStore.accounts.filter { $0.safeId != nil }
|
||||
}
|
||||
|
||||
private var visibleSections: [DashboardSectionConfig] {
|
||||
sectionConfigs.filter { $0.isVisible }
|
||||
}
|
||||
@@ -144,7 +151,16 @@ struct DashboardView: View {
|
||||
changeLabel: calmModeEnabled ? "since last update" : "today",
|
||||
isPositive: calmModeEnabled
|
||||
? viewModel.latestPortfolioChange.absolute >= 0
|
||||
: viewModel.isDayChangePositive
|
||||
: viewModel.isDayChangePositive,
|
||||
forecast: viewModel.portfolioForecast,
|
||||
isPremium: iapService.isPremium,
|
||||
onUnlockTap: {
|
||||
viewModel.showingPaywall = true
|
||||
},
|
||||
yearChange: viewModel.portfolioSummary.formattedYearChange,
|
||||
sinceInceptionChange: viewModel.portfolioSummary.formattedAllTimeReturn,
|
||||
isYearPositive: viewModel.isYearChangePositive,
|
||||
isSinceInceptionPositive: viewModel.portfolioSummary.allTimeReturn >= 0
|
||||
)
|
||||
}
|
||||
case .monthlyCheckIn:
|
||||
@@ -243,6 +259,13 @@ struct TotalValueCard: View {
|
||||
let changeText: String
|
||||
let changeLabel: String
|
||||
let isPositive: Bool
|
||||
var forecast: PortfolioForecast?
|
||||
var isPremium: Bool = false
|
||||
var onUnlockTap: (() -> Void)?
|
||||
var yearChange: String?
|
||||
var sinceInceptionChange: String?
|
||||
var isYearPositive: Bool = true
|
||||
var isSinceInceptionPositive: Bool = true
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 8) {
|
||||
@@ -264,6 +287,77 @@ struct TotalValueCard: View {
|
||||
.foregroundColor(.white.opacity(0.8))
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
|
||||
// YoY and Since Inception returns
|
||||
if yearChange != nil || sinceInceptionChange != nil {
|
||||
HStack(spacing: 16) {
|
||||
if let yearChange = yearChange {
|
||||
VStack(spacing: 2) {
|
||||
Text("YoY")
|
||||
.font(.caption2)
|
||||
.foregroundColor(.white.opacity(0.7))
|
||||
Text(yearChange)
|
||||
.font(.caption.weight(.semibold))
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}
|
||||
|
||||
if let sinceInceptionChange = sinceInceptionChange {
|
||||
VStack(spacing: 2) {
|
||||
Text("Since inception")
|
||||
.font(.caption2)
|
||||
.foregroundColor(.white.opacity(0.7))
|
||||
Text(sinceInceptionChange)
|
||||
.font(.caption.weight(.semibold))
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.top, 4)
|
||||
}
|
||||
|
||||
// Forecast section
|
||||
if let forecast = forecast {
|
||||
Divider()
|
||||
.background(Color.white.opacity(0.3))
|
||||
.padding(.vertical, 8)
|
||||
|
||||
if isPremium {
|
||||
VStack(spacing: 4) {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: "wand.and.stars")
|
||||
.font(.caption)
|
||||
Text("12-month forecast")
|
||||
.font(.caption)
|
||||
}
|
||||
.foregroundColor(.white.opacity(0.85))
|
||||
|
||||
Text(forecast.formattedForecastValue)
|
||||
.font(.title2.weight(.bold))
|
||||
.foregroundColor(.white)
|
||||
|
||||
Text(forecast.formattedGrowthPercentage)
|
||||
.font(.caption.weight(.semibold))
|
||||
.foregroundColor(forecast.isPositiveGrowth ? .white : .white.opacity(0.8))
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
onUnlockTap?()
|
||||
} label: {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: "lock.fill")
|
||||
.font(.caption)
|
||||
Text("Unlock 12-month forecast")
|
||||
.font(.caption.weight(.semibold))
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color.white.opacity(0.2))
|
||||
.cornerRadius(16)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 24)
|
||||
|
||||
Reference in New Issue
Block a user