summaryrefslogtreecommitdiff
path: root/Rune/Views/Settings
diff options
context:
space:
mode:
Diffstat (limited to 'Rune/Views/Settings')
-rw-r--r--Rune/Views/Settings/SettingsView.swift19
-rw-r--r--Rune/Views/Settings/WalletPaymentDetailView.swift45
-rw-r--r--Rune/Views/Settings/WalletTransactionsView.swift75
3 files changed, 134 insertions, 5 deletions
diff --git a/Rune/Views/Settings/SettingsView.swift b/Rune/Views/Settings/SettingsView.swift
index 4d07887..a776956 100644
--- a/Rune/Views/Settings/SettingsView.swift
+++ b/Rune/Views/Settings/SettingsView.swift
@@ -2,6 +2,7 @@ import SwiftUI
struct SettingsView: View {
@ObservedObject var viewModel: SettingsViewModel
+ @ObservedObject var walletViewModel: WalletViewModel
let onLogout: () -> Void
@State private var showingLogoutConfirmation = false
@@ -33,6 +34,12 @@ struct SettingsView: View {
}
}
.disabled(viewModel.client == nil || viewModel.isLoadingBalance)
+
+ if let client = viewModel.client {
+ NavigationLink("Transactions") {
+ WalletTransactionsView(viewModel: walletViewModel, client: client)
+ }
+ }
}
Section("Account") {
@@ -57,11 +64,13 @@ struct SettingsView: View {
titleVisibility: .visible
) {
Button("Log Out", role: .destructive) {
- do {
- try viewModel.logout()
- onLogout()
- } catch {
- viewModel.errorMessage = error.localizedDescription
+ Task {
+ do {
+ try await viewModel.logout()
+ onLogout()
+ } catch {
+ viewModel.errorMessage = error.localizedDescription
+ }
}
}
diff --git a/Rune/Views/Settings/WalletPaymentDetailView.swift b/Rune/Views/Settings/WalletPaymentDetailView.swift
new file mode 100644
index 0000000..f5ef605
--- /dev/null
+++ b/Rune/Views/Settings/WalletPaymentDetailView.swift
@@ -0,0 +1,45 @@
+import SwiftUI
+
+struct WalletPaymentDetailView: View {
+ let transactionID: String
+ @ObservedObject var viewModel: WalletViewModel
+ let client: NjallaClient
+
+ var body: some View {
+ Group {
+ if viewModel.isLoadingPayment && viewModel.selectedPayment == nil {
+ ProgressView("Loading Payment")
+ } else if let payment = viewModel.selectedPayment {
+ List {
+ Section("Payment") {
+ detailRow(label: "ID", value: payment.id ?? transactionID)
+ detailRow(label: "Status", value: payment.status ?? "Not available")
+ detailRow(label: "Amount", value: payment.amount.map { "€\($0)" } ?? "Not available")
+ detailRow(label: "Address", value: payment.address ?? "Not available")
+ detailRow(label: "URL", value: payment.url ?? "Not available")
+ }
+ }
+ .listStyle(.insetGrouped)
+ } else if let errorMessage = viewModel.paymentErrorMessage {
+ ContentUnavailableView("Payment Unavailable", systemImage: "exclamationmark.triangle", description: Text(errorMessage))
+ } else {
+ ContentUnavailableView("Payment Unavailable", systemImage: "creditcard", description: Text("No payment details were returned for this transaction."))
+ }
+ }
+ .navigationTitle("Payment")
+ .navigationBarTitleDisplayMode(.inline)
+ .task {
+ await viewModel.loadPayment(id: transactionID, client: client)
+ }
+ }
+
+ private func detailRow(label: String, value: String) -> some View {
+ HStack {
+ Text(label)
+ Spacer()
+ Text(value)
+ .foregroundStyle(.secondary)
+ .multilineTextAlignment(.trailing)
+ }
+ }
+}
diff --git a/Rune/Views/Settings/WalletTransactionsView.swift b/Rune/Views/Settings/WalletTransactionsView.swift
new file mode 100644
index 0000000..f0106de
--- /dev/null
+++ b/Rune/Views/Settings/WalletTransactionsView.swift
@@ -0,0 +1,75 @@
+import SwiftUI
+
+struct WalletTransactionsView: View {
+ @ObservedObject var viewModel: WalletViewModel
+ let client: NjallaClient
+
+ var body: some View {
+ List {
+ if let errorMessage = viewModel.transactionsErrorMessage {
+ Section {
+ InlineErrorView(message: errorMessage, retryTitle: "Retry Transactions") {
+ Task {
+ await viewModel.loadTransactions(client: client)
+ }
+ }
+ .listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
+ }
+ }
+
+ if viewModel.isLoadingTransactions && viewModel.transactions.isEmpty {
+ Section {
+ HStack {
+ Spacer()
+ ProgressView("Loading Transactions")
+ Spacer()
+ }
+ }
+ } else if viewModel.transactions.isEmpty {
+ Section {
+ ContentUnavailableView(
+ "No Transactions",
+ systemImage: "eurosign.circle",
+ description: Text("No wallet transactions were returned for this account.")
+ )
+ }
+ } else {
+ ForEach(viewModel.transactions) { transaction in
+ NavigationLink {
+ WalletPaymentDetailView(transactionID: transaction.id, viewModel: viewModel, client: client)
+ } label: {
+ VStack(alignment: .leading, spacing: 4) {
+ Text(transaction.type ?? "Transaction")
+ .font(.headline)
+ Text(transactionDateText(transaction))
+ .font(.subheadline)
+ .foregroundStyle(.secondary)
+ if let amount = transaction.amount {
+ Text("Amount: €\(amount)")
+ .font(.subheadline)
+ .foregroundStyle(.secondary)
+ }
+ }
+ .padding(.vertical, 4)
+ }
+ }
+ }
+ }
+ .listStyle(.insetGrouped)
+ .navigationTitle("Transactions")
+ .navigationBarTitleDisplayMode(.inline)
+ .task {
+ await viewModel.loadTransactions(client: client)
+ }
+ .refreshable {
+ await viewModel.loadTransactions(client: client)
+ }
+ }
+
+ private func transactionDateText(_ transaction: WalletTransaction) -> String {
+ if let date = transaction.date, !date.isEmpty {
+ return date
+ }
+ return "ID: \(transaction.id)"
+ }
+}