This commit is contained in:
2025-07-18 17:41:23 -04:00
parent 66f257609f
commit 34942bfc48
9 changed files with 337 additions and 111 deletions

View File

@ -14,83 +14,49 @@ struct SplitsView: View {
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@Query(sort: [
SortDescriptor(\Split.order),
SortDescriptor(\Split.name)
]) private var splits: [Split]
@State var splits: [Split] = []
@State private var showingAddSheet: Bool = false
@State private var allowSorting: Bool = true
var body: some View {
NavigationStack {
ScrollView {
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 16) {
ForEach(splits) { split in
SortableForEach($splits, allowReordering: $allowSorting) { split, dragging in
NavigationLink {
SplitExercisesListView(model: split)
} label: {
VStack {
ZStack(alignment: .bottom) {
// Golden ratio rectangle (1:1.618)
RoundedRectangle(cornerRadius: 12)
.fill(
LinearGradient(
gradient: Gradient(colors: [split.getColor(), split.getColor().darker(by: 0.2)]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.aspectRatio(1.618, contentMode: .fit)
.shadow(radius: 2)
VStack {
// Icon in the center
Image(systemName: split.systemImage)
.font(.system(size: 40, weight: .medium))
.foregroundColor(.white)
.offset(y: -15)
// Name at the bottom inside the rectangle
Text(split.name)
.font(.headline)
.foregroundColor(.white)
.lineLimit(1)
.padding(.horizontal, 8)
.padding(.bottom, 8)
}
}
// Exercise count below the rectangle
Text("\(split.exercises?.count ?? 0) exercises")
.font(.caption)
.foregroundColor(.secondary)
}
DraggableSplitItem(
name: split.name,
color: Color.color(from: split.color),
systemImageName: split.systemImage,
exerciseCount: split.exercises?.count ?? 0
)
.overlay(dragging ? Color.white.opacity(0.8) : Color.clear)
}
}
.onMove(perform: { indices, destination in
var splitArray = Array(splits)
splitArray.move(fromOffsets: indices, toOffset: destination)
for (index, split) in splitArray.enumerated() {
split.order = index
}
if let modelContext = splitArray.first?.modelContext {
do {
try modelContext.save()
} catch {
print("Error saving after reordering: \(error)")
}
}
})
}
.padding()
}
.navigationTitle("Splits")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: { showingAddSheet.toggle() }) {
Image(systemName: "plus")
.onAppear {
do {
self.splits = try modelContext.fetch(FetchDescriptor<Split>(
sortBy: [
SortDescriptor(\Split.order),
SortDescriptor(\Split.name)
]
))
} catch {
print("ERROR: failed to load splits \(error)")
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: { showingAddSheet.toggle() }) {
Image(systemName: "plus")
}
}
}
}