summaryrefslogtreecommitdiff
path: root/Rune/Views/Domains/DomainListView.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-24 21:48:23 -0500
committerChristian Cleberg <[email protected]>2026-03-24 21:48:23 -0500
commitcf587aa0573ac4f34e1effe70108a9eca82093ac (patch)
tree833e6f4961522e35b08af01b5f012983f8e34678 /Rune/Views/Domains/DomainListView.swift
downloadrune-cf587aa0573ac4f34e1effe70108a9eca82093ac.tar.gz
rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.tar.bz2
rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.zip
v1.0v1.0.0
Diffstat (limited to 'Rune/Views/Domains/DomainListView.swift')
-rw-r--r--Rune/Views/Domains/DomainListView.swift86
1 files changed, 86 insertions, 0 deletions
diff --git a/Rune/Views/Domains/DomainListView.swift b/Rune/Views/Domains/DomainListView.swift
new file mode 100644
index 0000000..d728bd7
--- /dev/null
+++ b/Rune/Views/Domains/DomainListView.swift
@@ -0,0 +1,86 @@
+import SwiftUI
+
+struct DomainListView: View {
+ @ObservedObject var viewModel: DomainViewModel
+ let client: NjallaClient?
+
+ var body: some View {
+ NavigationStack {
+ Group {
+ if let client {
+ content(client: client)
+ } else {
+ ContentUnavailableView("Sign in required", systemImage: "key.fill", description: Text("Add a valid Njalla API token to load domains."))
+ }
+ }
+ .navigationTitle("Domains")
+ }
+ .alert("API Error", isPresented: errorBinding) {
+ Button("OK", role: .cancel) {}
+ } message: {
+ Text(viewModel.errorMessage ?? "")
+ }
+ }
+
+ @ViewBuilder
+ private func content(client: NjallaClient) -> some View {
+ if viewModel.isLoadingDomains && viewModel.domains.isEmpty {
+ ProgressView()
+ } else if viewModel.domains.isEmpty {
+ ContentUnavailableView("No Domains", systemImage: "globe", description: Text("No domains found on this account."))
+ } else {
+ List(viewModel.domains) { domain in
+ NavigationLink {
+ DomainDetailView(domainName: domain.name, viewModel: viewModel, client: client)
+ } label: {
+ DomainRow(domain: domain)
+ }
+ }
+ .listStyle(.insetGrouped)
+ .refreshable {
+ await viewModel.loadDomains(client: client)
+ }
+ }
+ }
+
+ private var errorBinding: Binding<Bool> {
+ Binding(
+ get: { viewModel.errorMessage != nil },
+ set: { newValue in
+ if !newValue {
+ viewModel.errorMessage = nil
+ }
+ }
+ )
+ }
+}
+
+private struct DomainRow: View {
+ let domain: Domain
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 6) {
+ Text(domain.name)
+ .font(.headline)
+
+ HStack {
+ if let status = domain.status {
+ Text(status)
+ }
+
+ if let expiry = domain.expiry {
+ Text("Expiry: \(expiry.formattedExpiry())")
+ }
+ }
+ .font(.subheadline)
+ .foregroundStyle(.secondary)
+
+ if let autorenew = domain.autorenew {
+ Text(autorenew ? "Autorenew On" : "Autorenew Off")
+ .font(.subheadline)
+ .foregroundStyle(.secondary)
+ }
+ }
+ .padding(.vertical, 4)
+ }
+}