diff options
| author | Christian Cleberg <[email protected]> | 2026-03-24 21:48:23 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-24 21:48:23 -0500 |
| commit | cf587aa0573ac4f34e1effe70108a9eca82093ac (patch) | |
| tree | 833e6f4961522e35b08af01b5f012983f8e34678 /Rune/Views/Domains/DomainDetailView.swift | |
| download | rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.tar.gz rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.tar.bz2 rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.zip | |
v1.0v1.0.0
Diffstat (limited to 'Rune/Views/Domains/DomainDetailView.swift')
| -rw-r--r-- | Rune/Views/Domains/DomainDetailView.swift | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/Rune/Views/Domains/DomainDetailView.swift b/Rune/Views/Domains/DomainDetailView.swift new file mode 100644 index 0000000..dbb90a1 --- /dev/null +++ b/Rune/Views/Domains/DomainDetailView.swift @@ -0,0 +1,114 @@ +import SwiftUI + +struct DomainDetailView: View { + let domainName: String + @ObservedObject var viewModel: DomainViewModel + let client: NjallaClient + + var body: some View { + Group { + if viewModel.isLoadingDetail && viewModel.selectedDomain?.name != domainName { + ProgressView() + } else if let domain = currentDomain { + List { + Section("Status") { + DetailRow(label: "Name", value: domain.name) + DetailRow(label: "Status", value: textValue(domain.status)) + DetailRow(label: "Expiry", value: domain.expiry?.formattedExpiry() ?? "Not available") + DetailRow(label: "Autorenew", value: boolText(domain.autorenew)) + } + + Section("Settings") { + DetailRow(label: "Mail Forwarding", value: boolText(domain.mailforwarding)) + DetailRow(label: "DNSSEC", value: boolText(domain.dnssec)) + DetailRow(label: "Registrar Lock", value: boolText(domain.lock)) + DetailRow(label: "Nameservers", value: nameserverText(domain.nameservers)) + } + + Section("DNS") { + NavigationLink("Records") { + RecordListView(domainName: domain.name, viewModel: viewModel, client: client) + } + } + } + .listStyle(.insetGrouped) + .toolbar { + NavigationLink("Edit") { + DomainEditView(domain: domain, viewModel: viewModel, client: client) + } + } + } else { + ContentUnavailableView("Domain Unavailable", systemImage: "globe", description: Text("The domain details could not be loaded.")) + } + } + .navigationTitle(domainName) + .navigationBarTitleDisplayMode(.inline) + .task { + await viewModel.loadDomainDetail(named: domainName, client: client) + } + .alert("API Error", isPresented: errorBinding) { + Button("OK", role: .cancel) {} + } message: { + Text(viewModel.errorMessage ?? "") + } + } + + private var currentDomain: Domain? { + if viewModel.selectedDomain?.name == domainName { + return viewModel.selectedDomain + } + + return viewModel.domains.first(where: { $0.name == domainName }) + } + + private func boolText(_ value: Bool?) -> String { + guard let value else { return "Not available" } + return value ? "On" : "Off" + } + + private func nameserverText(_ nameservers: [String]?) -> String { + guard let nameservers else { + return "Not available" + } + + guard !nameservers.isEmpty else { + return "Default" + } + + return nameservers.joined(separator: ", ") + } + + private func textValue(_ value: String?) -> String { + guard let value, !value.isEmpty else { + return "Not available" + } + + return value + } + + private var errorBinding: Binding<Bool> { + Binding( + get: { viewModel.errorMessage != nil }, + set: { newValue in + if !newValue { + viewModel.errorMessage = nil + } + } + ) + } +} + +private struct DetailRow: View { + let label: String + let value: String + + var body: some View { + HStack { + Text(label) + Spacer() + Text(value) + .foregroundStyle(.secondary) + .multilineTextAlignment(.trailing) + } + } +} |
