wip
This commit is contained in:
@ -11,12 +11,14 @@ enum WorkoutStatus: Int, Codable {
|
|||||||
case notStarted = 1
|
case notStarted = 1
|
||||||
case inProgress = 2
|
case inProgress = 2
|
||||||
case completed = 3
|
case completed = 3
|
||||||
|
case skipped = 4
|
||||||
|
|
||||||
var checkboxStatus: CheckboxStatus {
|
var checkboxStatus: CheckboxStatus {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
case .notStarted: .unchecked
|
case .notStarted: .unchecked
|
||||||
case .inProgress: .intermediate
|
case .inProgress: .intermediate
|
||||||
case .completed: .checked
|
case .completed: .checked
|
||||||
|
case .skipped: .cancelled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
180
Workouts/Resources/exercises.yaml
Normal file
180
Workouts/Resources/exercises.yaml
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
- name: Lat Pull Down
|
||||||
|
setup: 'Seat: 3, Thigh Pad: 4'
|
||||||
|
descr: Sit upright with your knees secured under the pad. Grip the bar wider than
|
||||||
|
shoulder-width. Pull the bar down to your chest, squeezing your shoulder blades
|
||||||
|
together. Avoid leaning back excessively or using momentum.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Latissimus Dorsi
|
||||||
|
- Trapezius
|
||||||
|
- Rhomboids
|
||||||
|
- Biceps Brachii
|
||||||
|
- name: Seated Row
|
||||||
|
setup: 'Seat: 2, Chest Pad: 3'
|
||||||
|
descr: With your chest firmly against the pad, grip the handles and pull straight
|
||||||
|
back while keeping your elbows close to your body. Focus on retracting your shoulder
|
||||||
|
blades and avoid rounding your back.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Latissimus Dorsi
|
||||||
|
- Rhomboids
|
||||||
|
- Trapezius
|
||||||
|
- Biceps Brachii
|
||||||
|
- name: Shoulder Press
|
||||||
|
setup: 'Seat: 4'
|
||||||
|
descr: Sit with your back against the pad, grip the handles just outside shoulder-width.
|
||||||
|
Press upward without locking out your elbows. Keep your neck relaxed and avoid
|
||||||
|
shrugging your shoulders.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 30
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Deltoid (Anterior)
|
||||||
|
- Deltoid (Lateral)
|
||||||
|
- Triceps Brachii
|
||||||
|
- name: Chest Press
|
||||||
|
setup: 'Seat: 3'
|
||||||
|
descr: Adjust the seat so the handles are at mid-chest height. Push forward until
|
||||||
|
arms are nearly extended, then return slowly. Keep wrists straight and don’t let
|
||||||
|
your elbows drop too low.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 40
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Pectoralis Major
|
||||||
|
- Triceps Brachii
|
||||||
|
- Deltoid (Anterior)
|
||||||
|
- name: Tricep Press
|
||||||
|
setup: 'Seat: 2'
|
||||||
|
descr: With elbows close to your sides, press the handles downward in a controlled
|
||||||
|
motion. Avoid flaring your elbows or using your shoulders to assist the motion.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Triceps Brachii
|
||||||
|
- name: Arm Curl
|
||||||
|
setup: 'Seat: 3'
|
||||||
|
descr: Position your arms over the pad and grip the handles. Curl the weight upward
|
||||||
|
while keeping your upper arms stationary. Avoid using momentum and fully control
|
||||||
|
the lowering phase.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 30
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Biceps Brachii
|
||||||
|
- Brachialis
|
||||||
|
- name: Abdominal
|
||||||
|
setup: 'Seat: 2, Back Pad: 3'
|
||||||
|
descr: Sit with the pads resting against your chest. Contract your abs to curl forward,
|
||||||
|
keeping your lower back in contact with the pad. Avoid pulling with your arms
|
||||||
|
or hips.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Rectus Abdominis
|
||||||
|
- Internal Obliques
|
||||||
|
- name: Rotary
|
||||||
|
setup: 'Seat: 3, Start Angle: Centered'
|
||||||
|
descr: Rotate your torso from side to side in a controlled motion, keeping your
|
||||||
|
hips still. Focus on using your obliques to generate the twist, not momentum or
|
||||||
|
the arms.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Internal Obliques
|
||||||
|
- External Obliques
|
||||||
|
- name: Leg Press
|
||||||
|
setup: 'Seat Angle: 4, Platform: Middle'
|
||||||
|
descr: Place your feet shoulder-width on the platform. Press upward through your
|
||||||
|
heels without locking your knees. Keep your back flat against the pad throughout
|
||||||
|
the motion.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 130
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Gluteus Maximus
|
||||||
|
- Rectus Femoris
|
||||||
|
- Vastus Lateralis
|
||||||
|
- Vastus Medialis
|
||||||
|
- Vastus Intermedius
|
||||||
|
- Biceps Femoris
|
||||||
|
- Semitendinosus
|
||||||
|
- Semimembranosus
|
||||||
|
- name: Leg Extension
|
||||||
|
setup: 'Seat: 3, Pad: Above ankle'
|
||||||
|
descr: Sit upright and align your knees with the pivot point. Extend your legs to
|
||||||
|
a straightened position, then lower with control. Avoid jerky movements or lifting
|
||||||
|
your hips off the seat.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 70
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Rectus Femoris
|
||||||
|
- Vastus Lateralis
|
||||||
|
- Vastus Medialis
|
||||||
|
- Vastus Intermedius
|
||||||
|
- name: Leg Curl
|
||||||
|
setup: 'Seat: 2, Pad: Above ankle'
|
||||||
|
descr: Lie face down or sit depending on the version. Curl your legs toward your
|
||||||
|
glutes, focusing on hamstring engagement. Avoid arching your back or using momentum.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Biceps Femoris
|
||||||
|
- Semitendinosus
|
||||||
|
- Semimembranosus
|
||||||
|
- name: Adductor
|
||||||
|
setup: 'Seat: 3, Start Position: Wide'
|
||||||
|
descr: Sit with legs placed outside the pads. Bring your legs together using inner
|
||||||
|
thigh muscles. Control the motion both in and out, avoiding fast swings.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 110
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Adductor Longus
|
||||||
|
- Adductor Brevis
|
||||||
|
- Adductor Magnus
|
||||||
|
- Gracilis
|
||||||
|
- name: Abductor
|
||||||
|
setup: 'Seat: 3, Start Position: Narrow'
|
||||||
|
descr: Sit with legs inside the pads and push outward to engage outer thighs and
|
||||||
|
glutes. Avoid leaning forward and keep the motion controlled throughout.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 110
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Gluteus Medius
|
||||||
|
- Tensor Fasciae Latae
|
||||||
|
- name: Calfs
|
||||||
|
setup: 'Seat: 3, Toe Bar: Midfoot'
|
||||||
|
descr: Place the balls of your feet on the platform with heels hanging off. Raise
|
||||||
|
your heels by contracting your calves, then slowly lower them below the platform
|
||||||
|
level for a full stretch.
|
||||||
|
sets: 3
|
||||||
|
reps: 10
|
||||||
|
weight: 60
|
||||||
|
type: Machine-Based
|
||||||
|
muscles:
|
||||||
|
- Gastrocnemius
|
||||||
|
- Soleus
|
@ -13,12 +13,14 @@ enum CheckboxStatus {
|
|||||||
case checked
|
case checked
|
||||||
case unchecked
|
case unchecked
|
||||||
case intermediate
|
case intermediate
|
||||||
|
case cancelled
|
||||||
|
|
||||||
var color: Color {
|
var color: Color {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
case .checked: .green
|
case .checked: .green
|
||||||
case .unchecked: .gray
|
case .unchecked: .gray
|
||||||
case .intermediate: .yellow
|
case .intermediate: .yellow
|
||||||
|
case .cancelled: .red
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +29,7 @@ enum CheckboxStatus {
|
|||||||
case .checked: "checkmark.circle.fill"
|
case .checked: "checkmark.circle.fill"
|
||||||
case .unchecked: "circle"
|
case .unchecked: "circle"
|
||||||
case .intermediate: "ellipsis.circle"
|
case .intermediate: "ellipsis.circle"
|
||||||
|
case .cancelled: "cross.circle"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
Workouts/Utils/Color+darker.swift
Normal file
30
Workouts/Utils/Color+darker.swift
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Color+darker.swift
|
||||||
|
// Workouts
|
||||||
|
//
|
||||||
|
// Created by rzen on 7/17/25 at 9:20 AM.
|
||||||
|
//
|
||||||
|
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension Color {
|
||||||
|
func darker(by percentage: CGFloat) -> Color {
|
||||||
|
let uiColor = UIColor(self)
|
||||||
|
var hue: CGFloat = 0
|
||||||
|
var saturation: CGFloat = 0
|
||||||
|
var brightness: CGFloat = 0
|
||||||
|
var alpha: CGFloat = 0
|
||||||
|
|
||||||
|
if uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) {
|
||||||
|
let newBrightness = max(brightness * (1 - percentage), 0)
|
||||||
|
let darkerUIColor = UIColor(hue: hue, saturation: saturation, brightness: newBrightness, alpha: alpha)
|
||||||
|
return Color(darkerUIColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self // Fallback if color can't be converted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,21 +30,37 @@ struct SplitPickerView: View {
|
|||||||
dismiss()
|
dismiss()
|
||||||
}) {
|
}) {
|
||||||
VStack {
|
VStack {
|
||||||
ZStack {
|
ZStack(alignment: .bottom) {
|
||||||
|
// Golden ratio rectangle (1:1.618)
|
||||||
RoundedRectangle(cornerRadius: 12)
|
RoundedRectangle(cornerRadius: 12)
|
||||||
.fill(split.getColor())
|
.fill(
|
||||||
.aspectRatio(1, contentMode: .fit)
|
LinearGradient(
|
||||||
|
gradient: Gradient(colors: [split.getColor(), split.getColor().darker(by: 0.2)]),
|
||||||
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.aspectRatio(1.618, contentMode: .fit)
|
||||||
.shadow(radius: 2)
|
.shadow(radius: 2)
|
||||||
|
|
||||||
|
VStack {
|
||||||
|
// Icon in the center
|
||||||
Image(systemName: split.systemImage)
|
Image(systemName: split.systemImage)
|
||||||
.font(.system(size: 30))
|
.font(.system(size: 40, weight: .medium))
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
}
|
.offset(y: -15)
|
||||||
|
|
||||||
|
// Name at the bottom inside the rectangle
|
||||||
Text(split.name)
|
Text(split.name)
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
|
.foregroundColor(.white)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
.padding(.bottom, 8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise count below the rectangle
|
||||||
Text("\(split.exercises?.count ?? 0) exercises")
|
Text("\(split.exercises?.count ?? 0) exercises")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
|
@ -40,11 +40,12 @@ struct WorkoutsView: View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||||
Button(role: .destructive) {
|
Button {
|
||||||
itemToDelete = workout
|
itemToDelete = workout
|
||||||
} label: {
|
} label: {
|
||||||
Label("Delete", systemImage: "trash")
|
Label("Delete", systemImage: "trash")
|
||||||
}
|
}
|
||||||
|
.tint(.red)
|
||||||
Button {
|
Button {
|
||||||
itemToEdit = workout
|
itemToEdit = workout
|
||||||
} label: {
|
} label: {
|
||||||
@ -77,11 +78,13 @@ struct WorkoutsView: View {
|
|||||||
) {
|
) {
|
||||||
Button("Delete", role: .destructive) {
|
Button("Delete", role: .destructive) {
|
||||||
if let item = itemToDelete {
|
if let item = itemToDelete {
|
||||||
|
withAnimation {
|
||||||
modelContext.delete(item)
|
modelContext.delete(item)
|
||||||
try? modelContext.save()
|
try? modelContext.save()
|
||||||
itemToDelete = nil
|
itemToDelete = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Button("Cancel", role: .cancel) {
|
Button("Cancel", role: .cancel) {
|
||||||
itemToDelete = nil
|
itemToDelete = nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user