Files
Sportstime/SportsTime/Features/Progress/Views/StadiumVisitHistoryView.swift
Trey t 89167c01d7 feat(progress): add progress tracking enhancements
- Enable zoom/pan on progress map with reset button
- Add visit count badges to stadium chips
- Create GamesHistoryView with year grouping and sport filters
- Create StadiumVisitHistoryView for viewing all visits to a stadium
- Add VisitListCard and GamesHistoryRow components
- Add "See All" navigation from Recent Visits to Games History
- Add tests for map interactions, visit lists, and games history

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 21:34:33 -06:00

110 lines
3.1 KiB
Swift

import SwiftUI
import SwiftData
struct StadiumVisitHistoryView: View {
let stadium: Stadium
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@State private var visits: [StadiumVisit] = []
@State private var isLoading = true
@State private var showingAddVisit = false
var body: some View {
NavigationStack {
Group {
if isLoading {
ProgressView()
} else if visits.isEmpty {
EmptyVisitHistoryView()
} else {
VisitHistoryList(visits: visits)
}
}
.navigationTitle(stadium.name)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Done") { dismiss() }
}
ToolbarItem(placement: .primaryAction) {
Button {
showingAddVisit = true
} label: {
Image(systemName: "plus")
}
}
}
.sheet(isPresented: $showingAddVisit) {
StadiumVisitSheet(initialStadium: stadium)
}
}
.task {
await loadVisits()
}
}
private func loadVisits() async {
isLoading = true
defer { isLoading = false }
let stadiumId = stadium.id
let descriptor = FetchDescriptor<StadiumVisit>(
predicate: #Predicate { $0.stadiumId == stadiumId },
sortBy: [SortDescriptor(\.visitDate, order: .reverse)]
)
do {
visits = try modelContext.fetch(descriptor)
} catch {
visits = []
}
}
}
private struct VisitHistoryList: View {
let visits: [StadiumVisit]
var body: some View {
ScrollView {
VStack(spacing: 12) {
// Visit count header
HStack {
Text("\(visits.count) Visit\(visits.count == 1 ? "" : "s")")
.font(.headline)
Spacer()
}
.padding(.horizontal)
// Visit cards
ForEach(visits, id: \.id) { visit in
VisitListCard(visit: visit)
.padding(.horizontal)
}
}
.padding(.vertical)
}
.background(Color(.systemGroupedBackground))
}
}
private struct EmptyVisitHistoryView: View {
var body: some View {
VStack(spacing: 16) {
Image(systemName: "calendar.badge.plus")
.font(.system(size: 48))
.foregroundStyle(.secondary)
Text("No visits recorded")
.font(.headline)
Text("Tap + to add your first visit to this stadium")
.font(.subheadline)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
.padding()
}
}