krz/rune
an ios client for njalla
clone: git clone https://gitbay.org/krz/rune.git
main: Rune/Views/Settings/SettingsView.swift · raw
1import SwiftUI
2
3struct SettingsView: View {
4 @ObservedObject var viewModel: SettingsViewModel
5 @ObservedObject var walletViewModel: WalletViewModel
6 let onLogout: () -> Void
7 @State private var showingLogoutConfirmation = false
8
9 var body: some View {
10 NavigationStack {
11 List {
12 Section("Wallet") {
13 if let balance = viewModel.balance {
14 HStack {
15 Text("Balance")
16 Spacer()
17 Text("€\(balance.balance)")
18 .foregroundStyle(.secondary)
19 }
20 } else if viewModel.isLoadingBalance {
21 ProgressView()
22 } else {
23 Text("Wallet balance unavailable.")
24 .foregroundStyle(.secondary)
25 }
26
27 Button("Refresh Balance") {
28 Task {
29 do {
30 try await viewModel.refreshBalance()
31 } catch {
32 viewModel.errorMessage = error.localizedDescription
33 }
34 }
35 }
36 .disabled(viewModel.client == nil || viewModel.isLoadingBalance)
37
38 if let client = viewModel.client {
39 NavigationLink("Transactions") {
40 WalletTransactionsView(viewModel: walletViewModel, client: client)
41 }
42 }
43 }
44
45 Section("Account") {
46 Button("Logout", role: .destructive) {
47 showingLogoutConfirmation = true
48 }
49 .foregroundStyle(.red)
50 }
51
52 if let errorMessage = viewModel.errorMessage {
53 Section {
54 Text(errorMessage)
55 .foregroundStyle(.red)
56 }
57 }
58 }
59 .navigationTitle("Settings")
60 }
61 .confirmationDialog(
62 "Log out of Rune?",
63 isPresented: $showingLogoutConfirmation,
64 titleVisibility: .visible
65 ) {
66 Button("Log Out", role: .destructive) {
67 Task {
68 do {
69 try await viewModel.logout()
70 onLogout()
71 } catch {
72 viewModel.errorMessage = error.localizedDescription
73 }
74 }
75 }
76
77 Button("Cancel", role: .cancel) {}
78 } message: {
79 Text("Your API token will be removed from this device.")
80 }
81 }
82}