1.1.0 feature work: Monthly Check-in, Charts, Goals, Share, Reviews
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -160,7 +160,18 @@ struct DashboardView: View {
|
||||
yearChange: viewModel.portfolioSummary.formattedYearChange,
|
||||
sinceInceptionChange: viewModel.portfolioSummary.formattedAllTimeReturn,
|
||||
isYearPositive: viewModel.isYearChangePositive,
|
||||
isSinceInceptionPositive: viewModel.portfolioSummary.allTimeReturn >= 0
|
||||
isSinceInceptionPositive: viewModel.portfolioSummary.allTimeReturn >= 0,
|
||||
onShareTap: {
|
||||
ShareService.shared.sharePortfolioValue(
|
||||
totalValue: viewModel.portfolioSummary.formattedTotalValue,
|
||||
changeText: calmModeEnabled
|
||||
? "\(viewModel.latestPortfolioChange.formattedAbsolute) (\(viewModel.latestPortfolioChange.formattedPercentage))"
|
||||
: viewModel.portfolioSummary.formattedDayChange,
|
||||
changeLabel: calmModeEnabled ? "since last check-in" : "today",
|
||||
yearChange: viewModel.portfolioSummary.formattedYearChange,
|
||||
sinceInceptionChange: viewModel.portfolioSummary.formattedAllTimeReturn
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
case .monthlyCheckIn:
|
||||
@@ -210,11 +221,12 @@ struct DashboardView: View {
|
||||
CategoryBreakdownCard(categories: viewModel.topCategories)
|
||||
}
|
||||
case .goals:
|
||||
let homeGoals = goalsViewModel.goals.filter { !GoalsViewModel.isAchieved(progress: goalsViewModel.progress(for: $0)) }
|
||||
if config.isCollapsed {
|
||||
CompactCard(title: "Goals", subtitle: "\(goalsViewModel.goals.count) active")
|
||||
CompactCard(title: "Goals", subtitle: "\(homeGoals.count) active")
|
||||
} else {
|
||||
GoalsSummaryCard(
|
||||
goals: goalsViewModel.goals,
|
||||
goals: homeGoals,
|
||||
progressProvider: goalsViewModel.progress(for:),
|
||||
currentValueProvider: goalsViewModel.totalValue(for:),
|
||||
paceStatusProvider: goalsViewModel.paceStatus(for:),
|
||||
@@ -266,12 +278,24 @@ struct TotalValueCard: View {
|
||||
var sinceInceptionChange: String?
|
||||
var isYearPositive: Bool = true
|
||||
var isSinceInceptionPositive: Bool = true
|
||||
var onShareTap: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 8) {
|
||||
Text("Total Portfolio Value")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.white.opacity(0.85))
|
||||
ZStack(alignment: .trailing) {
|
||||
Text("Total Portfolio Value")
|
||||
.font(.headline.weight(.semibold))
|
||||
.foregroundColor(.white.opacity(0.85))
|
||||
|
||||
if let onShareTap {
|
||||
Button(action: onShareTap) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
.font(.subheadline.weight(.semibold))
|
||||
.foregroundColor(.white.opacity(0.9))
|
||||
}
|
||||
.padding(.trailing, 8)
|
||||
}
|
||||
}
|
||||
|
||||
Text(totalValue)
|
||||
.font(.system(size: 42, weight: .bold, design: .rounded))
|
||||
@@ -423,13 +447,6 @@ struct MonthlyCheckInCard: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
NavigationLink {
|
||||
AchievementsView(referenceDate: Date())
|
||||
} label: {
|
||||
Image(systemName: "trophy.fill")
|
||||
}
|
||||
.font(.subheadline.weight(.semibold))
|
||||
|
||||
if let reminderDate {
|
||||
Button {
|
||||
let title = String(
|
||||
@@ -1053,6 +1070,12 @@ struct GoalsSummaryCard: View {
|
||||
ForEach(goals.prefix(2)) { goal in
|
||||
let currentValue = currentValueProvider(goal)
|
||||
let paceStatus = paceStatusProvider(goal)
|
||||
let isAchieved = GoalsViewModel.isAchieved(progress: progressProvider(goal))
|
||||
let targetUrgency = GoalsViewModel.urgencyLevel(
|
||||
targetDate: goal.targetDate,
|
||||
isBehind: paceStatus?.isBehind ?? false,
|
||||
isAchieved: isAchieved
|
||||
)
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
HStack {
|
||||
Text(goal.name)
|
||||
@@ -1083,6 +1106,12 @@ struct GoalsSummaryCard: View {
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
if let targetDate = goal.targetDate {
|
||||
Text("Target: \(targetDate.mediumDateString)")
|
||||
.font(.caption2.weight(.semibold))
|
||||
.foregroundColor(targetUrgency == .critical ? .negativeRed : (targetUrgency == .warning ? .appWarning : .secondary))
|
||||
}
|
||||
|
||||
if let etaText = etaProvider(goal) {
|
||||
Text(etaText)
|
||||
.font(.caption2)
|
||||
|
||||
Reference in New Issue
Block a user