47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import type { StrengthExercise, StrengthWorkout } from "@/lib/models/strength";
|
|
|
|
export function exerciseVolumeKg(exercise: StrengthExercise): number {
|
|
return exercise.sets.reduce((sum, set) => sum + (set.weightKg ?? 0) * (set.reps ?? 0), 0);
|
|
}
|
|
|
|
export function exerciseTopWeightKg(exercise: StrengthExercise): number | undefined {
|
|
const weights = exercise.sets
|
|
.map((set) => set.weightKg)
|
|
.filter((weight): weight is number => weight !== undefined);
|
|
return weights.length > 0 ? Math.max(...weights) : undefined;
|
|
}
|
|
|
|
export function workoutVolumeKg(workout: StrengthWorkout): number {
|
|
return workout.exercises.reduce((sum, exercise) => sum + exerciseVolumeKg(exercise), 0);
|
|
}
|
|
|
|
export type ExerciseHistoryPoint = {
|
|
date: Date;
|
|
volumeKg: number;
|
|
topWeightKg?: number;
|
|
};
|
|
|
|
/**
|
|
* History of a single exercise across past workouts (oldest first, including
|
|
* the workout it was found in), used to chart progression.
|
|
*/
|
|
export function getExerciseHistory(
|
|
exerciseName: string,
|
|
workouts: StrengthWorkout[],
|
|
limit: number
|
|
): ExerciseHistoryPoint[] {
|
|
const points: ExerciseHistoryPoint[] = [];
|
|
for (const workout of workouts) {
|
|
const exercise = workout.exercises.find((e) => e.name === exerciseName);
|
|
if (!exercise) continue;
|
|
points.push({
|
|
date: workout.date,
|
|
volumeKg: exerciseVolumeKg(exercise),
|
|
topWeightKg: exerciseTopWeightKg(exercise),
|
|
});
|
|
}
|
|
|
|
points.sort((a, b) => a.date.getTime() - b.date.getTime());
|
|
return points.slice(-limit);
|
|
}
|