Overview
The routine types define the structure for workout routines, including workout plans, summaries, and category data. These types provide comprehensive type safety for managing structured workout programs.
IRoutine
Represents a complete workout routine with all associated data.
interface IRoutine {
category : string [];
routine : {
routine_title : string ;
routine_description : string ;
routine_imageUrl : string ;
workout_plan : { heading : string ; day_plan : string }[];
workout_summary : {
MainGoal : string ;
WorkoutType : string ;
TrainingLevel : string ;
ProgramDuration : string ;
DaysPerWeek : number ;
TimePerWorkout : string ;
EquipmentRequired : string ;
TargetGender : string ;
};
};
id_ : number ;
id : number ;
}
Properties
Array of category tags for the routine (e.g., [“strength”, “beginner”, “full-body”])
Main routine object containing all workout details Title of the workout routine
Detailed description of the routine, goals, and approach
Featured image URL for the routine
Array of daily workout plans Show workout_plan item properties
Day or phase heading (e.g., “Day 1: Chest & Triceps”)
Detailed plan for the day including exercises, sets, and reps
Summary of routine characteristics and requirements Show workout_summary properties
Primary goal of the routine (e.g., “Build Muscle”, “Lose Fat”)
Type of workout (e.g., “Split”, “Full Body”)
Required experience level (e.g., “Beginner”, “Intermediate”, “Advanced”)
Total duration of the program (e.g., “8 weeks”, “12 weeks”)
Number of training days per week
Average time per workout session (e.g., “60 minutes”)
Equipment needed for the routine (e.g., “Barbell, Dumbbells, Bench”)
Target gender for the routine (e.g., “Male”, “Female”, “Unisex”)
Alternative numeric identifier for the routine
Primary numeric identifier for the routine
IRoutinesResponse
Paginated response containing multiple routines.
interface IRoutinesResponse {
totalPages : number ;
totalRoutines : number ;
data : IRoutine [];
}
Properties
Total number of pages available for pagination
Total count of routines matching the query
Array of routine objects for the current page
IRoutineCategory
Represents a routine category with visual representation.
interface IRoutineCategory {
title : string ;
imageUrl : string ;
}
Properties
Category title (e.g., “Strength Training”, “Weight Loss”)
Image URL representing the category
IRoutineCategoryResponse
Response containing routine categories and count.
interface IRoutineCategoryResponse {
data : {
category : IRoutineCategory [];
};
totalRoutinesFilter : number ;
}
Properties
Container for category data category
IRoutineCategory[]
required
Array of available routine categories
Total number of routines available across all categories
Usage Examples
Fetching Routines
Routine Categories
Workout Plan Display
React Component
Filtering Routines
import { IRoutinesResponse , IRoutine } from './types' ;
async function getRoutines (
page : number = 1 ,
category ?: string
) : Promise < IRoutinesResponse > {
const params = new URLSearchParams ({ page: page . toString () });
if ( category ) params . append ( 'category' , category );
const response = await fetch (
`https://api.bodyworks.io/routines? ${ params } `
);
return response . json ();
}
// Type-safe usage
const routines = await getRoutines ( 1 , 'strength' );
console . log ( `Total: ${ routines . totalRoutines } ` );
console . log ( `Pages: ${ routines . totalPages } ` );
routines . data . forEach (( routine : IRoutine ) => {
console . log ( routine . routine . routine_title );
console . log ( `Days/Week: ${ routine . routine . workout_summary . DaysPerWeek } ` );
});
import { IRoutineCategoryResponse , IRoutineCategory } from './types' ;
async function getCategories () : Promise < IRoutineCategory []> {
const response = await fetch (
'https://api.bodyworks.io/routines/categories'
);
const result : IRoutineCategoryResponse = await response . json ();
return result . data . category ;
}
// Display categories
const categories = await getCategories ();
categories . forEach (( cat ) => {
console . log ( ` ${ cat . title } : ${ cat . imageUrl } ` );
});
import { IRoutine } from './types' ;
function displayWorkoutPlan ( routine : IRoutine ) : void {
console . log ( ` \n ${ routine . routine . routine_title } ` );
console . log ( '=' . repeat ( 50 ));
console . log ( routine . routine . routine_description );
console . log ( ' \n Workout Plan:' );
routine . routine . workout_plan . forEach (( day , index ) => {
console . log ( ` \n ${ day . heading } ` );
console . log ( day . day_plan );
});
console . log ( ' \n Summary:' );
const summary = routine . routine . workout_summary ;
console . log ( `Goal: ${ summary . MainGoal } ` );
console . log ( `Level: ${ summary . TrainingLevel } ` );
console . log ( `Duration: ${ summary . ProgramDuration } ` );
console . log ( `Days/Week: ${ summary . DaysPerWeek } ` );
console . log ( `Time/Workout: ${ summary . TimePerWorkout } ` );
}
import React , { useState , useEffect } from 'react' ;
import { IRoutine , IRoutinesResponse } from './types' ;
interface RoutineCardProps {
routine : IRoutine ;
}
const RoutineCard : React . FC < RoutineCardProps > = ({ routine }) => {
const { routine : r } = routine ;
return (
< div className = "routine-card" >
< img src = {r. routine_imageUrl } alt = {r. routine_title } />
< h3 >{r. routine_title } </ h3 >
< p >{r. routine_description } </ p >
< div className = "summary" >
< span > Level : { r . workout_summary . TrainingLevel }</ span >
< span > Days : { r . workout_summary . DaysPerWeek }/ week </ span >
< span > Duration : { r . workout_summary . ProgramDuration }</ span >
</ div >
< div className = "categories" >
{ routine . category . map (( cat , idx ) => (
< span key = { idx } className = "badge" > { cat } </ span >
))}
</ div >
</ div >
);
};
export const RoutineList : React . FC = () => {
const [ routines , setRoutines ] = useState < IRoutine []>([]);
const [ loading , setLoading ] = useState ( true );
useEffect (() => {
async function fetchRoutines () {
const response = await fetch ( 'https://api.bodyworks.io/routines' );
const data : IRoutinesResponse = await response . json ();
setRoutines ( data . data );
setLoading ( false );
}
fetchRoutines ();
}, []);
if ( loading ) return < div > Loading ...</ div > ;
return (
< div className = "routine-list" >
{ routines . map (( routine ) => (
< RoutineCard key = {routine. id } routine = { routine } />
))}
</ div >
);
};
import { IRoutinesResponse , IRoutine } from './types' ;
interface RoutineFilters {
level ?: string ;
daysPerWeek ?: number ;
goal ?: string ;
}
function filterRoutines (
response : IRoutinesResponse ,
filters : RoutineFilters
) : IRoutine [] {
return response . data . filter (( routine ) => {
const summary = routine . routine . workout_summary ;
if ( filters . level && summary . TrainingLevel !== filters . level ) {
return false ;
}
if ( filters . daysPerWeek && summary . DaysPerWeek !== filters . daysPerWeek ) {
return false ;
}
if ( filters . goal && summary . MainGoal !== filters . goal ) {
return false ;
}
return true ;
});
}
// Usage
const allRoutines = await getRoutines ();
const beginnerRoutines = filterRoutines ( allRoutines , {
level: 'Beginner' ,
daysPerWeek: 3
});
Type Guards
Create type guards to safely validate routine data:
function isValidWorkoutSummary ( obj : any ) : boolean {
return (
typeof obj === 'object' &&
typeof obj . MainGoal === 'string' &&
typeof obj . WorkoutType === 'string' &&
typeof obj . TrainingLevel === 'string' &&
typeof obj . ProgramDuration === 'string' &&
typeof obj . DaysPerWeek === 'number' &&
typeof obj . TimePerWorkout === 'string' &&
typeof obj . EquipmentRequired === 'string' &&
typeof obj . TargetGender === 'string'
);
}
function isValidRoutine ( obj : any ) : obj is IRoutine {
return (
typeof obj === 'object' &&
Array . isArray ( obj . category ) &&
typeof obj . routine === 'object' &&
typeof obj . routine . routine_title === 'string' &&
typeof obj . routine . routine_description === 'string' &&
Array . isArray ( obj . routine . workout_plan ) &&
isValidWorkoutSummary ( obj . routine . workout_summary ) &&
typeof obj . id === 'number' &&
typeof obj . id_ === 'number'
);
}