// // SplitListView.swift // Workouts // // Created by rzen on 7/25/25 at 6:24 PM. // // Copyright 2025 Rouslan Zenetl. All Rights Reserved. // import SwiftUI import SwiftData /// The Splits library screen, pushed from Settings → Library: a plain list of /// splits, one row each. Tapping a row opens `SplitDetailView`; long-pressing /// offers Delete (the sole split-delete affordance); the toolbar's + adds a new /// split. Starter splits are seeded automatically on the true first run /// (`SyncEngine.autoSeedIfEmpty`), so an empty library just invites creating one. struct SplitListView: View { @Environment(SyncEngine.self) private var sync @Query(sort: \Split.name) private var splits: [Split] @State private var showingAddSheet = false @State private var splitToDelete: Split? var body: some View { List { ForEach(splits) { split in NavigationLink { SplitDetailView(split: split) } label: { SplitRow(split: split) } .contextMenu { Button(role: .destructive) { splitToDelete = split } label: { Label("Delete", systemImage: "trash") } } } } .listStyle(.insetGrouped) .overlay { if splits.isEmpty { ContentUnavailableView( "No Splits Yet", systemImage: "dumbbell.fill", description: Text("Create a split to organize your workout routine.") ) } } .navigationTitle("Splits") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { showingAddSheet = true } label: { Image(systemName: "plus") } .accessibilityLabel("Add Split") } } .sheet(isPresented: $showingAddSheet) { SplitAddEditView(split: nil) } .confirmationDialog( "Delete Split?", isPresented: Binding( get: { splitToDelete != nil }, set: { if !$0 { splitToDelete = nil } } ), titleVisibility: .visible, presenting: splitToDelete ) { split in Button("Delete", role: .destructive) { Task { await sync.delete(split: split) } splitToDelete = nil } Button("Cancel", role: .cancel) { splitToDelete = nil } } message: { split in Text("This will permanently delete \"\(split.name)\" and all its exercises. Past workouts are kept.") } } } /// A single split row: a small rounded-square badge (the split's color at low /// opacity, its symbol tinted full-strength) beside the split name and its /// exercise count. private struct SplitRow: View { var split: Split var body: some View { HStack(spacing: 12) { Image(systemName: split.systemImage) .font(.title3) .foregroundStyle(splitColor) .frame(width: 36, height: 36) .background(splitColor.opacity(0.12), in: RoundedRectangle(cornerRadius: 8)) VStack(alignment: .leading, spacing: 2) { Text(split.name) .foregroundStyle(.primary) Text("\(split.exercisesArray.count) exercises") .font(.caption) .foregroundStyle(.secondary) } } .padding(.vertical, 2) } private var splitColor: Color { Color.color(from: split.color) } }