// // GymsView.swift // OpenClimb // // Created by OpenClimb on 2025-01-17. // import SwiftUI struct GymsView: View { @EnvironmentObject var dataManager: ClimbingDataManager @State private var showingAddGym = false var body: some View { NavigationView { VStack { if dataManager.gyms.isEmpty { EmptyGymsView() } else { GymsList() } } .navigationTitle("Gyms") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Add") { showingAddGym = true } } } .sheet(isPresented: $showingAddGym) { AddEditGymView() } } } } struct GymsList: View { @EnvironmentObject var dataManager: ClimbingDataManager var body: some View { List(dataManager.gyms, id: \.id) { gym in NavigationLink(destination: GymDetailView(gymId: gym.id)) { GymRow(gym: gym) } } .listStyle(.plain) } } struct GymRow: View { let gym: Gym @EnvironmentObject var dataManager: ClimbingDataManager private var problemCount: Int { dataManager.problems(forGym: gym.id).count } private var sessionCount: Int { dataManager.sessions(forGym: gym.id).count } var body: some View { VStack(alignment: .leading, spacing: 12) { // Header VStack(alignment: .leading, spacing: 4) { Text(gym.name) .font(.headline) .fontWeight(.bold) if let location = gym.location, !location.isEmpty { Text(location) .font(.subheadline) .foregroundColor(.secondary) } } // Climb Types if !gym.supportedClimbTypes.isEmpty { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 8) { ForEach(gym.supportedClimbTypes, id: \.self) { climbType in Text(climbType.displayName) .font(.caption) .padding(.horizontal, 8) .padding(.vertical, 4) .background( RoundedRectangle(cornerRadius: 8) .fill(.blue.opacity(0.1)) ) .foregroundColor(.blue) } } } } // Difficulty Systems if !gym.difficultySystems.isEmpty { Text( "Systems: \(gym.difficultySystems.map { $0.displayName }.joined(separator: ", "))" ) .font(.caption) .foregroundColor(.secondary) } // Stats HStack { Label("\(problemCount)", systemImage: "star.fill") .font(.caption) .foregroundColor(.orange) Label("\(sessionCount)", systemImage: "play.fill") .font(.caption) .foregroundColor(.green) Spacer() } // Notes preview if let notes = gym.notes, !notes.isEmpty { Text(notes) .font(.caption) .foregroundColor(.secondary) .lineLimit(2) } } .padding(.vertical, 4) } } struct EmptyGymsView: View { @State private var showingAddGym = false var body: some View { VStack(spacing: 20) { Spacer() Image(systemName: "location.fill") .font(.system(size: 60)) .foregroundColor(.secondary) VStack(spacing: 8) { Text("No Gyms Added") .font(.title2) .fontWeight(.bold) Text("Add your favorite climbing gyms to start tracking your progress!") .font(.body) .foregroundColor(.secondary) .multilineTextAlignment(.center) .padding(.horizontal) } Button("Add Gym") { showingAddGym = true } .buttonStyle(.borderedProminent) .controlSize(.large) Spacer() } .sheet(isPresented: $showingAddGym) { AddEditGymView() } } } #Preview { GymsView() .environmentObject(ClimbingDataManager.preview) }