mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-22 16:51:33 +00:00
166 lines
3.5 KiB
TypeScript
166 lines
3.5 KiB
TypeScript
![]() |
// types/workout.ts - handles how exercises are combined and tracked in workouts
|
||
|
|
||
|
import { BaseExercise, WorkoutExercise } from './exercise';
|
||
|
|
||
|
export type TemplateCategory =
|
||
|
| 'Full Body'
|
||
|
| 'Custom'
|
||
|
| 'Push/Pull/Legs'
|
||
|
| 'Upper/Lower'
|
||
|
| 'Cardio'
|
||
|
| 'CrossFit'
|
||
|
| 'Strength';
|
||
|
|
||
|
// Base state that all workout types extend
|
||
|
interface BaseWorkoutState {
|
||
|
id: string;
|
||
|
title: string;
|
||
|
description?: string;
|
||
|
notes: string;
|
||
|
created_at: number;
|
||
|
availability: {
|
||
|
source: ('local' | 'nostr' | 'backup')[];
|
||
|
lastSynced?: {
|
||
|
backup?: number;
|
||
|
nostr?: {
|
||
|
timestamp: number;
|
||
|
metadata: {
|
||
|
id: string;
|
||
|
pubkey: string;
|
||
|
relayUrl: string;
|
||
|
created_at: number;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Active workout state used in WorkoutContext
|
||
|
export interface WorkoutState extends BaseWorkoutState {
|
||
|
startTime: Date | null;
|
||
|
endTime: Date | null;
|
||
|
isActive: boolean;
|
||
|
exercises: WorkoutExercise[];
|
||
|
totalTime: number;
|
||
|
isPaused: boolean;
|
||
|
totalWeight: number;
|
||
|
templateSource?: {
|
||
|
id: string;
|
||
|
title: string;
|
||
|
category: TemplateCategory;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Workout template definition
|
||
|
export interface WorkoutTemplate extends BaseWorkoutState {
|
||
|
type: 'strength' | 'circuit' | 'emom' | 'amrap';
|
||
|
category: TemplateCategory;
|
||
|
exercises: Array<{
|
||
|
exercise: BaseExercise;
|
||
|
targetSets: number;
|
||
|
targetReps: number;
|
||
|
notes?: string;
|
||
|
}>;
|
||
|
author?: {
|
||
|
name: string;
|
||
|
pubkey?: string;
|
||
|
};
|
||
|
metadata?: {
|
||
|
lastUsed?: number;
|
||
|
useCount?: number;
|
||
|
averageDuration?: number;
|
||
|
};
|
||
|
isPublic: boolean;
|
||
|
tags: string[];
|
||
|
rounds?: number;
|
||
|
duration?: number; // in seconds
|
||
|
interval?: number; // in seconds
|
||
|
restBetweenRounds?: number; // in seconds
|
||
|
}
|
||
|
|
||
|
// Completed workout record
|
||
|
export interface WorkoutRecord extends BaseWorkoutState {
|
||
|
exercises: Array<{
|
||
|
exercise: BaseExercise;
|
||
|
sets: Array<{
|
||
|
weight: number;
|
||
|
reps: number;
|
||
|
type: 'warmup' | 'normal' | 'drop' | 'failure';
|
||
|
isCompleted: boolean;
|
||
|
}>;
|
||
|
totalWeight: number;
|
||
|
}>;
|
||
|
startTime: number;
|
||
|
endTime: number;
|
||
|
totalWeight: number;
|
||
|
templateId?: string;
|
||
|
metrics?: {
|
||
|
totalTime: number;
|
||
|
totalVolume: number;
|
||
|
exerciseCount: number;
|
||
|
setCount: number;
|
||
|
personalBests: Array<{
|
||
|
exerciseId: string;
|
||
|
metric: 'weight' | 'reps' | 'volume';
|
||
|
value: number;
|
||
|
}>;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Exercise progress tracking
|
||
|
export interface ExerciseProgress {
|
||
|
exerciseId: string;
|
||
|
history: Array<{
|
||
|
date: number;
|
||
|
workoutId: string;
|
||
|
weight: number;
|
||
|
reps: number;
|
||
|
volume: number;
|
||
|
}>;
|
||
|
personalBests: {
|
||
|
weight?: {
|
||
|
value: number;
|
||
|
date: number;
|
||
|
workoutId: string;
|
||
|
};
|
||
|
reps?: {
|
||
|
value: number;
|
||
|
date: number;
|
||
|
workoutId: string;
|
||
|
};
|
||
|
volume?: {
|
||
|
value: number;
|
||
|
date: number;
|
||
|
workoutId: string;
|
||
|
};
|
||
|
};
|
||
|
trends: {
|
||
|
lastMonth: {
|
||
|
workouts: number;
|
||
|
volumeChange: number;
|
||
|
weightChange: number;
|
||
|
};
|
||
|
lastYear: {
|
||
|
workouts: number;
|
||
|
volumeChange: number;
|
||
|
weightChange: number;
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Type guard functions
|
||
|
export function isWorkoutTemplate(workout: any): workout is WorkoutTemplate {
|
||
|
return workout &&
|
||
|
'type' in workout &&
|
||
|
'category' in workout &&
|
||
|
'exercises' in workout &&
|
||
|
Array.isArray(workout.exercises);
|
||
|
}
|
||
|
|
||
|
export function isWorkoutRecord(workout: any): workout is WorkoutRecord {
|
||
|
return workout &&
|
||
|
'startTime' in workout &&
|
||
|
'endTime' in workout &&
|
||
|
'exercises' in workout &&
|
||
|
Array.isArray(workout.exercises);
|
||
|
}
|