Files
aris-old/IrisCompanion/iris/Views/CandidatesView.swift

114 lines
3.6 KiB
Swift

//
// CandidatesView.swift
// iris
//
// Created by Codex.
//
import SwiftUI
struct CandidatesView: View {
@StateObject private var model = CandidatesViewModel()
var body: some View {
NavigationStack {
List {
Section("Source") {
LabeledContent("Location") {
Text("London (demo)")
}
if let updated = model.lastUpdatedAt {
LabeledContent("Last update") { Text(timeOnly(from: updated)) }
} else {
LabeledContent("Last update") { Text("Never") }
}
if let error = model.lastError {
Text(error)
.font(.footnote)
.foregroundStyle(.secondary)
}
}
if !model.diagnostics.isEmpty {
Section("Diagnostics") {
ForEach(model.diagnostics.keys.sorted(), id: \.self) { key in
LabeledContent(key) {
Text(model.diagnostics[key] ?? "")
.font(.caption)
.foregroundStyle(.secondary)
.textSelection(.enabled)
}
}
}
}
Section("Candidates (\(model.candidates.count))") {
if model.candidates.isEmpty {
Text(model.isLoading ? "Loading…" : "No candidates")
.foregroundStyle(.secondary)
} else {
ForEach(model.candidates, id: \.id) { candidate in
CandidateRow(candidate: candidate)
}
}
}
}
.navigationTitle("Candidates")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button(model.isLoading ? "Refreshing…" : "Refresh") {
model.refresh()
}
.disabled(model.isLoading)
}
}
.onAppear { model.refresh() }
}
}
private func timeOnly(from date: Date) -> String {
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .medium
return formatter.string(from: date)
}
}
private struct CandidateRow: View {
let candidate: FeedItem
var body: some View {
VStack(alignment: .leading, spacing: 6) {
HStack(alignment: .firstTextBaseline) {
Text(candidate.title)
.font(.headline)
.lineLimit(1)
Spacer()
Text(candidate.type.rawValue)
.font(.caption)
.foregroundStyle(.secondary)
}
if !candidate.subtitle.isEmpty {
Text(candidate.subtitle)
.font(.subheadline)
.foregroundStyle(.secondary)
.lineLimit(1)
}
HStack(spacing: 12) {
Text(String(format: "prio %.2f", candidate.priority))
Text("ttl \(candidate.ttlSec)s")
}
.font(.caption)
.foregroundStyle(.secondary)
}
.padding(.vertical, 4)
}
}
struct CandidatesView_Previews: PreviewProvider {
static var previews: some View {
CandidatesView()
}
}