Update budget details view and fix some loading issues
This commit is contained in:
parent
5fd73bf0bc
commit
c5647a0553
6 changed files with 77 additions and 59 deletions
|
@ -10,45 +10,66 @@ import SwiftUI
|
|||
|
||||
struct BudgetDetailsView: View {
|
||||
@EnvironmentObject var budgetDataStore: BudgetsDataStore
|
||||
@State var requestedOverview = ""
|
||||
let budget: Budget
|
||||
|
||||
@ViewBuilder
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack {
|
||||
switch budgetDataStore.overview {
|
||||
case .failure(.loading):
|
||||
ActivityIndicator(isAnimating: .constant(true), style: .large)
|
||||
case .success(let overview):
|
||||
Text("current_balance")
|
||||
Text(verbatim: overview.balance.toCurrencyString())
|
||||
.foregroundColor(overview.balance < 0 ? .red : .green)
|
||||
Text("expected_income")
|
||||
Text(verbatim: overview.expectedIncome.toCurrencyString())
|
||||
Text("actual_income")
|
||||
Text(verbatim: overview.actualIncome.toCurrencyString())
|
||||
.foregroundColor(.green)
|
||||
Text("expected_expenses")
|
||||
Text(verbatim: overview.expectedExpenses.toCurrencyString())
|
||||
Text("actual_expenses")
|
||||
Text(verbatim: overview.actualExpenses.toCurrencyString())
|
||||
.foregroundColor(.red)
|
||||
default:
|
||||
Text("An error has ocurred")
|
||||
switch budgetDataStore.overview {
|
||||
case .failure(.loading):
|
||||
ActivityIndicator(isAnimating: .constant(true), style: .large)
|
||||
case .success(let overview):
|
||||
List {
|
||||
Section(overview.budget.name) {
|
||||
VStack(alignment: .leading) {
|
||||
if let description = overview.budget.description {
|
||||
Text(description)
|
||||
}
|
||||
HStack {
|
||||
Text("current_balance")
|
||||
Text(verbatim: overview.balance.toCurrencyString())
|
||||
.foregroundColor(overview.balance < 0 ? .red : .green)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.onAppear {
|
||||
if requestedOverview != budget.id {
|
||||
requestedOverview = budget.id
|
||||
budgetDataStore.loadOverview(budget)
|
||||
Section("income") {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text("expected")
|
||||
Text(verbatim: overview.expectedIncome.toCurrencyString())
|
||||
}
|
||||
ProgressView(value: Float(overview.expectedIncome), maxValue: Float(max(overview.expectedIncome, overview.actualIncome)), progressTintColor: .gray, progressBarHeight: 10.0, progressBarCornerRadius: 4.0)
|
||||
HStack {
|
||||
Text("actual")
|
||||
Text(verbatim: overview.actualIncome.toCurrencyString())
|
||||
.foregroundColor(.green)
|
||||
}
|
||||
ProgressView(value: Float(overview.actualIncome), maxValue: Float(max(overview.expectedIncome, overview.actualIncome)), progressTintColor: .green, progressBarHeight: 10.0, progressBarCornerRadius: 4.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
Section("expenses") {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text("expected")
|
||||
Text(verbatim: overview.expectedExpenses.toCurrencyString())
|
||||
}
|
||||
ProgressView(value: Float(overview.expectedExpenses), maxValue: Float(max(overview.expectedExpenses, overview.actualExpenses)), progressTintColor: .gray, progressBarHeight: 10.0, progressBarCornerRadius: 4.0)
|
||||
HStack {
|
||||
Text("actual")
|
||||
Text(verbatim: overview.actualExpenses.toCurrencyString())
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
ProgressView(value: Float(overview.actualExpenses), maxValue: Float(max(overview.expectedExpenses, overview.actualExpenses)), progressTintColor: .red, progressBarHeight: 10.0, progressBarCornerRadius: 4.0)
|
||||
}
|
||||
}
|
||||
}.listStyle(.insetGrouped)
|
||||
.navigationBarItems(leading: HStack {
|
||||
Button("budgets", action: {
|
||||
self.budgetDataStore.showBudgetSelection = true
|
||||
}).padding()
|
||||
})
|
||||
default:
|
||||
Text("An error has ocurred")
|
||||
}
|
||||
.navigationBarItems(trailing: HStack {
|
||||
Button("budgets", action: {
|
||||
self.budgetDataStore.deselectBudget()
|
||||
}).padding()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,6 @@ struct BudgetListsView: View {
|
|||
self.budgetDataStore.getBudgets()
|
||||
})
|
||||
}
|
||||
}.onAppear {
|
||||
self.budgetDataStore.getBudgets()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,17 +19,13 @@ class BudgetsDataStore: ObservableObject {
|
|||
didSet {
|
||||
if case let .success(budget) = self.budget {
|
||||
UserDefaults.standard.set(budget.id, forKey: LAST_BUDGET)
|
||||
self.showBudgetSelection = false
|
||||
loadOverview(budget)
|
||||
}
|
||||
}
|
||||
}
|
||||
@Published var overview: Result<BudgetOverview, NetworkError> = .failure(.loading)
|
||||
|
||||
var showBudgetSelection: Bool {
|
||||
get {
|
||||
return self.budget == nil
|
||||
}
|
||||
set { }
|
||||
}
|
||||
@Published var showBudgetSelection: Bool = true
|
||||
|
||||
init(budgetRepository: BudgetRepository, categoryRepository: CategoryRepository, transactionRepository: TransactionRepository) {
|
||||
self.budgetRepository = budgetRepository
|
||||
|
@ -62,7 +58,9 @@ class BudgetsDataStore: ObservableObject {
|
|||
}
|
||||
}, receiveValue: { (budgets) in
|
||||
self.budgets = .success(budgets.sorted(by: { $0.name < $1.name }))
|
||||
if self.budget != nil {
|
||||
if case .success(_) = self.budget {
|
||||
// Don't do anything here
|
||||
} else {
|
||||
if let id = UserDefaults.standard.string(forKey: LAST_BUDGET) {
|
||||
if let budget = budgets.first(where: { $0.id == id }) {
|
||||
self.budget = .success(budget)
|
||||
|
@ -70,7 +68,11 @@ class BudgetsDataStore: ObservableObject {
|
|||
self.budget = nil
|
||||
}
|
||||
} else {
|
||||
self.budget = nil
|
||||
if let budget = budgets.first {
|
||||
self.budget = .success(budget)
|
||||
} else {
|
||||
self.budget = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -174,14 +176,8 @@ class BudgetsDataStore: ObservableObject {
|
|||
}
|
||||
|
||||
func selectBudget(_ budget: Budget) {
|
||||
self.objectWillChange.send()
|
||||
self.budget = .success(budget)
|
||||
}
|
||||
|
||||
func deselectBudget() {
|
||||
self.objectWillChange.send()
|
||||
self.budget = nil
|
||||
}
|
||||
}
|
||||
|
||||
private let LAST_BUDGET = "LAST_BUDGET"
|
||||
|
|
|
@ -71,7 +71,7 @@ struct TabbedBudgetView: View {
|
|||
.keyboardShortcut("4")
|
||||
}
|
||||
} else {
|
||||
Text("Loading…")
|
||||
ActivityIndicator(isAnimating: .constant(true), style: .large)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,12 +83,15 @@ struct TabbedBudgetView: View {
|
|||
content: {
|
||||
LoginView()
|
||||
.environmentObject(authenticationDataStore)
|
||||
.onDisappear {
|
||||
self.budgetDataStore.getBudgets()
|
||||
}
|
||||
}).sheet(isPresented: $budgetDataStore.showBudgetSelection,
|
||||
content: {
|
||||
BudgetListsView()
|
||||
.environmentObject(budgetDataStore)
|
||||
})
|
||||
.interactiveDismissDisabled(!hasSelectedBudget)
|
||||
.interactiveDismissDisabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@
|
|||
"budget" = "Budget";
|
||||
"budgets" = "Budgets";
|
||||
"current_balance" = "Current Balance:";
|
||||
"expected_income" = "Expected Income:";
|
||||
"actual_income" = "Actual Income:";
|
||||
"expected_expenses" = "Expected Expenses:";
|
||||
"actual_expenses" = "Actual Expenses:";
|
||||
"expected" = "Expected:";
|
||||
"actual" = "Actual:";
|
||||
"income" = "Income:";
|
||||
"expenses" = "Expenses:";
|
||||
|
||||
// MARK: Profile
|
||||
"profile" = "Profile";
|
||||
|
|
|
@ -62,10 +62,10 @@
|
|||
"budget" = "Presupuesto";
|
||||
"budgets" = "Presupuestos";
|
||||
"current_balance" = "Saldo Actual:";
|
||||
"expected_income" = "Ingresos Estimados:";
|
||||
"actual_income" = "Ingresos Actuales:";
|
||||
"expected_expenses" = "Gastos Estimados:";
|
||||
"actual_expenses" = "Gastos Actuales:";
|
||||
"income" = "Ingresos:";
|
||||
"expenses" = "Gastos:";
|
||||
"expected" = "Planeados:";
|
||||
"actual" = "Actuales:";
|
||||
|
||||
|
||||
// MARK: Profile
|
||||
|
|
Loading…
Reference in a new issue