Skip to content

Commit 0d04da7

Browse files
committed
Minor errors fixed
1 parent 01da743 commit 0d04da7

File tree

3 files changed

+67
-30
lines changed

3 files changed

+67
-30
lines changed

KonditionExpo/contexts/WorkoutContext.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useAuth } from '@/contexts/AuthContext'; // adjust if needed
55
export interface Exercise {
66
id: string;
77
name: string;
8+
description?: string;
89
muscle_group: string;
910
type: 'strength' | 'cardio' | 'flexibility';
1011
}
@@ -64,11 +65,27 @@ export const WorkoutProvider = ({ children }: { children: ReactNode }) => {
6465

6566
const generateId = () => Math.random().toString(36).substr(2, 9);
6667

68+
const transformWorkoutForBackend = (workout: Workout) => ({
69+
name: workout.name,
70+
description: workout.notes || null,
71+
scheduled_date: workout.date.toISOString(),
72+
duration_minutes: workout.duration,
73+
exercises: workout.exercises.map(ex => ({
74+
name: ex.exercise.name,
75+
description: ex.exercise.description || null,
76+
category: ex.exercise.muscle_group, // or ex.exercise.type if that's better
77+
sets: ex.sets.length,
78+
reps: ex.sets.reduce((sum, s) => sum + (s.reps || 0), 0),
79+
weight: ex.sets.reduce((max, s) => Math.max(max, s.weight || 0), 0),
80+
})),
81+
});
82+
6783
const addWorkout = async (workout: Workout) => {
6884
try {
85+
const payload = transformWorkoutForBackend(workout);
6986
const response = await axios.post(
7087
'http://localhost:8000/api/v1/workouts/', // Replace with deployment endpoint
71-
workout,
88+
payload,
7289
{
7390
headers: {
7491
Authorization: `Bearer ${token}`,
@@ -77,7 +94,16 @@ export const WorkoutProvider = ({ children }: { children: ReactNode }) => {
7794
);
7895
console.log("Response from POST /workouts: ", response);
7996
const savedWorkout = response.data;
80-
setWorkouts(prev => [...prev, savedWorkout]);
97+
98+
const saved = {
99+
...response.data,
100+
date: new Date(response.data.created_at),
101+
exercises: [], // if backend doesn't return them
102+
duration: response.data.duration_minutes || 0,
103+
};
104+
105+
setWorkouts(prev => [...prev, saved]);
106+
81107
} catch (error) {
82108
console.error('Failed to save workout to backend:', error.response?.data || error.message);
83109
}

backend/app/api/routes/workouts.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,26 @@
1414
WorkoutPublic,
1515
WorkoutsPublic,
1616
WorkoutWithExercisesPublic,
17+
WorkoutWithExercisesCreate,
1718
Exercise,
1819
ExerciseCreate,
1920
ExerciseUpdate,
2021
ExercisePublic,
22+
ExerciseNestedCreate
2123
)
2224
from app.crudFuncs import update_personal_bests_after_workout
2325

2426

2527
router = APIRouter(prefix="/workouts", tags=["workouts"])
2628

2729

28-
@router.post("/", response_model=WorkoutPublic)
30+
@router.post("/", response_model=WorkoutWithExercisesPublic)
2931
def create_workout(
3032
*,
3133
session: SessionDep,
3234
current_user: CurrentUser,
33-
workout_in: WorkoutCreate = Body(
34-
...,
35-
examples=[
36-
{
37-
"name": "Monday Strength Training",
38-
"description": "Focus on upper body strength",
39-
"scheduled_date": "2025-05-20T08:00:00Z",
40-
"duration_minutes": 60
41-
}
42-
],
43-
)
35+
workout_in: WorkoutWithExercisesCreate
4436
) -> Any:
45-
"""
46-
Create a new workout.
47-
48-
This endpoint allows users to create a new workout plan with details such as name,
49-
description, scheduled date, and expected duration.
50-
51-
- **name**: Required. The name of the workout (1-255 characters)
52-
- **description**: Optional. A detailed description of the workout (up to 1000 characters)
53-
- **scheduled_date**: Optional. When the workout is scheduled to take place
54-
- **duration_minutes**: Optional. The expected duration of the workout in minutes
55-
56-
Returns the created workout with its ID and other metadata.
57-
"""
5837
workout = Workout(
5938
user_id=current_user.id,
6039
name=workout_in.name,
@@ -64,13 +43,33 @@ def create_workout(
6443
is_completed=False,
6544
created_at=datetime.utcnow(),
6645
)
67-
46+
6847
session.add(workout)
6948
session.commit()
7049
session.refresh(workout)
71-
72-
return workout
7350

51+
# Add nested exercises
52+
for ex in workout_in.exercises:
53+
exercise = Exercise(
54+
workout_id=workout.id,
55+
name=ex.name,
56+
description=ex.description,
57+
category=ex.category,
58+
sets=ex.sets,
59+
reps=ex.reps,
60+
weight=ex.weight,
61+
)
62+
session.add(exercise)
63+
64+
session.commit()
65+
session.refresh(workout)
66+
67+
# Load exercises manually
68+
workout.exercises = session.exec(
69+
select(Exercise).where(Exercise.workout_id == workout.id)
70+
).all()
71+
72+
return workout
7473

7574
@router.get("/", response_model=WorkoutsPublic)
7675
def get_workouts(

backend/app/models/workout.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ class WorkoutsPublic(SQLModel):
149149
data: List[WorkoutPublic]
150150
count: int
151151

152+
class ExerciseNestedCreate(SQLModel):
153+
name: str
154+
description: Optional[str] = None
155+
category: str
156+
sets: Optional[int] = None
157+
reps: Optional[int] = None
158+
weight: Optional[float] = None
159+
160+
161+
class WorkoutWithExercisesCreate(WorkoutCreate):
162+
exercises: List[ExerciseNestedCreate] = []
163+
152164
#Personal Bests Model - Related to Workouts
153165
class PersonalBest(SQLModel, table=True):
154166
id: UUID = Field(default_factory=uuid4, primary_key=True)

0 commit comments

Comments
 (0)