POWR/types/workout.ts

166 lines
3.5 KiB
TypeScript
Raw Normal View History

// 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);
}