Activación: valor inicial como primer check-in + CTA en Quick Update vacío (build 84) #37

- AddSourceView: sección de valor reencuadrada como 'Valor de hoy' (primer check-in); si se omite, abre AddSnapshotView automáticamente en vez de dejar al usuario en el dashboard vacío
- QuickUpdateView: estado sin fuentes ahora tiene CTA 'Añade tu primera fuente' → .openAddFirstSource
- 3 claves nuevas localizadas en los 7 idiomas
- Bump a 1.6.1 (84)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VXtwQP6nYnbLFVqsHiTK5G
This commit is contained in:
alexandrev-tibco
2026-08-23 12:37:58 +02:00
parent 3b1f62cc26
commit f2f54a5ca3
10 changed files with 93 additions and 29 deletions
@@ -11,6 +11,9 @@ struct AddSourceView: View {
@State private var showingCategoryPicker = false
@State private var selectedAccountId: UUID?
@State private var duplicateError: String?
// Set when the source was saved without a value routes the user straight
// into their first check-in instead of dropping them on an empty dashboard.
@State private var pendingSnapshotSource: InvestmentSource?
@StateObject private var categoryRepository = CategoryRepository()
@StateObject private var sourceRepository = InvestmentSourceRepository()
@@ -83,7 +86,8 @@ struct AddSourceView: View {
}
}
// Initial Value (Optional)
// Today's value becomes the first snapshot. Framed as the default
// (not "optional"): most users who skipped it never recorded a check-in.
Section {
HStack {
Text(currencySymbol)
@@ -93,9 +97,9 @@ struct AddSourceView: View {
.keyboardType(.decimalPad)
}
} header: {
Text("Initial Value (Optional)")
Text(String(localized: "add_source_value_header"))
} footer: {
Text("You can add snapshots later if you prefer.")
Text(String(localized: "add_source_value_footer"))
}
}
.navigationTitle("Add Source")
@@ -121,6 +125,9 @@ struct AddSourceView: View {
categories: categoryRepository.categories
)
}
.sheet(item: $pendingSnapshotSource, onDismiss: { dismiss() }) { source in
AddSnapshotView(source: source)
}
.onAppear {
categoryRepository.createDefaultCategoriesIfNeeded()
if selectedCategory == nil {
@@ -166,6 +173,7 @@ struct AddSourceView: View {
)
// Add initial snapshot if provided
let hasInitialSnapshot: Bool
if let value = parseDecimal(initialValue), value > 0 {
let snapshotRepository = SnapshotRepository()
snapshotRepository.createSnapshot(
@@ -173,6 +181,9 @@ struct AddSourceView: View {
date: Date(),
value: value
)
hasInitialSnapshot = true
} else {
hasInitialSnapshot = false
}
// Schedule notification
@@ -190,7 +201,13 @@ struct AddSourceView: View {
sourceCount: repository.sourceCount
)
dismiss()
if hasInitialSnapshot {
dismiss()
} else {
// No value entered: open the first check-in right away so the user
// reaches the moment of value instead of an empty dashboard.
pendingSnapshotSource = source
}
}
private func parseDecimal(_ string: String) -> Decimal? {