Overview
Goal storage functions manage user-defined target weights for exercises. Goals are stored as a key-value mapping where exercise names are keys and target weights are values. This allows users to set specific weight targets they want to achieve by the end of the program.
Storage Key
Stores a JSON-serialized object mapping exercise names to goal weights
Data Structure
Goals are stored as a simple object:
{
"Squat" : 315 ,
"Bench Press" : 225 ,
"Deadlift" : 405 ,
"Overhead Press" : 135
}
Functions
getGoalWeights
Retrieves all goal weights from storage as an object mapping exercise names to weights.
async function getGoalWeights () : Promise < Record < string , number >>
Object mapping exercise names to goal weights, or empty object if none exist
Example
import { getGoalWeights } from '@/lib/storage' ;
const goals = await getGoalWeights ();
console . log ( goals );
// {
// "Squat": 315,
// "Bench Press": 225,
// "Deadlift": 405
// }
// Iterate over goals
Object . entries ( goals ). forEach (([ exercise , weight ]) => {
console . log ( `Goal for ${ exercise } : ${ weight } lbs` );
});
Source Code Reference
See implementation at lib/storage.ts:192-203
saveGoalWeights
Saves the complete goal weights object to storage, overwriting existing data.
async function saveGoalWeights (
goalWeights : Record < string , number >
) : Promise < void >
goalWeights
Record<string, number>
required
Object mapping exercise names to target weights
This function overwrites all existing goals. Load current goals with getGoalWeights() first if you need to preserve existing data.
Example
import { getGoalWeights , saveGoalWeights } from '@/lib/storage' ;
// Load existing goals
const goals = await getGoalWeights ();
// Add or modify goals
goals [ 'Front Squat' ] = 275 ;
goals [ 'Squat' ] = 335 ; // Update existing
// Save back to storage
await saveGoalWeights ( goals );
Source Code Reference
See implementation at lib/storage.ts:205-213
getGoalWeight
Retrieves the goal weight for a specific exercise by name.
async function getGoalWeight ( exerciseName : string ) : Promise < number | null >
The exact name of the exercise (case-sensitive)
The goal weight if set, or null if no goal exists for that exercise
Exercise names must match exactly. “Squat” and “squat” are treated as different exercises.
Example
import { getGoalWeight } from '@/lib/storage' ;
const squatGoal = await getGoalWeight ( 'Squat' );
if ( squatGoal ) {
console . log ( `Your squat goal is ${ squatGoal } lbs` );
} else {
console . log ( 'No goal set for Squat' );
}
Source Code Reference
See implementation at lib/storage.ts:215-218
setGoalWeight
Sets or updates the goal weight for a specific exercise.
async function setGoalWeight (
exerciseName : string ,
weight : number
) : Promise < void >
The target weight to achieve
This function loads existing goals, updates the specific exercise, and saves back to storage automatically.
Example
import { setGoalWeight } from '@/lib/storage' ;
// Set a new goal
await setGoalWeight ( 'Squat' , 315 );
// Update an existing goal
await setGoalWeight ( 'Squat' , 335 );
Source Code Reference
See implementation at lib/storage.ts:220-227
Common Patterns
Building a Goal Setting Interface
import { getExercises } from '@/lib/storage' ;
import { getGoalWeight , setGoalWeight } from '@/lib/storage' ;
import { useState , useEffect } from 'react' ;
function GoalSetter () {
const [ exercises , setExercises ] = useState < Exercise []>([]);
const [ goals , setGoals ] = useState < Record < string , number >>({});
useEffect (() => {
loadData ();
}, []);
async function loadData () {
const exerciseList = await getExercises ();
setExercises ( exerciseList );
// Load goal for each exercise
const goalData : Record < string , number > = {};
for ( const ex of exerciseList ) {
const goal = await getGoalWeight ( ex . name );
if ( goal ) {
goalData [ ex . name ] = goal ;
}
}
setGoals ( goalData );
}
async function updateGoal ( exerciseName : string , weight : number ) {
await setGoalWeight ( exerciseName , weight );
setGoals ({ ... goals , [exerciseName]: weight });
}
return (
< View >
{ exercises . map (( ex ) => (
< View key = {ex. id } >
< Text >{ex. name } </ Text >
< TextInput
keyboardType = "numeric"
value = {goals [ex.name]?.toString() || ''}
onChangeText={(val) => updateGoal(ex.name, Number(val))}
placeholder="Goal weight"
/>
</View>
))}
</View>
);
}
Calculating Progress Toward Goals
import { getGoalWeight } from '@/lib/storage' ;
import { getLoggedWorkouts } from '@/lib/storage' ;
async function calculateProgress ( exerciseName : string ) {
const goal = await getGoalWeight ( exerciseName );
if ( ! goal ) {
return null ;
}
// Find highest weight logged for this exercise
const workouts = await getLoggedWorkouts ();
let maxWeight = 0 ;
workouts . forEach (( workout ) => {
workout . exercises . forEach (( ex ) => {
if ( ex . exercise === exerciseName ) {
ex . sets . forEach (( set ) => {
const weight = typeof set . weight === 'number' ? set . weight : parseFloat ( set . weight );
if ( weight > maxWeight ) {
maxWeight = weight ;
}
});
}
});
});
const progress = ( maxWeight / goal ) * 100 ;
return {
current: maxWeight ,
goal ,
progress: Math . round ( progress ),
remaining: goal - maxWeight
};
}
// Usage
const squatProgress = await calculateProgress ( 'Squat' );
if ( squatProgress ) {
console . log ( `Current: ${ squatProgress . current } lbs` );
console . log ( `Goal: ${ squatProgress . goal } lbs` );
console . log ( `Progress: ${ squatProgress . progress } %` );
console . log ( `Remaining: ${ squatProgress . remaining } lbs to go` );
}
Bulk Goal Import
import { saveGoalWeights } from '@/lib/storage' ;
async function importGoalsFromTemplate ( template : 'beginner' | 'intermediate' | 'advanced' ) {
const templates = {
beginner: {
'Squat' : 225 ,
'Bench Press' : 185 ,
'Deadlift' : 315 ,
'Overhead Press' : 115
},
intermediate: {
'Squat' : 315 ,
'Bench Press' : 225 ,
'Deadlift' : 405 ,
'Overhead Press' : 155
},
advanced: {
'Squat' : 405 ,
'Bench Press' : 315 ,
'Deadlift' : 495 ,
'Overhead Press' : 205
}
};
await saveGoalWeights ( templates [ template ]);
}
// Usage
await importGoalsFromTemplate ( 'intermediate' );
Goal Tracking Dashboard
import { getGoalWeights } from '@/lib/storage' ;
import { getLoggedWorkouts } from '@/lib/storage' ;
async function getGoalsDashboard () {
const goals = await getGoalWeights ();
const workouts = await getLoggedWorkouts ();
// Calculate max weight for each exercise
const maxWeights : Record < string , number > = {};
workouts . forEach (( workout ) => {
workout . exercises . forEach (( ex ) => {
ex . sets . forEach (( set ) => {
const weight = typeof set . weight === 'number' ? set . weight : parseFloat ( set . weight );
if ( ! maxWeights [ ex . exercise ] || weight > maxWeights [ ex . exercise ]) {
maxWeights [ ex . exercise ] = weight ;
}
});
});
});
// Build dashboard data
return Object . entries ( goals ). map (([ exercise , goal ]) => ({
exercise ,
goal ,
current: maxWeights [ exercise ] || 0 ,
progress: maxWeights [ exercise ] ? Math . round (( maxWeights [ exercise ] / goal ) * 100 ) : 0 ,
achieved: ( maxWeights [ exercise ] || 0 ) >= goal
}));
}
// Usage
const dashboard = await getGoalsDashboard ();
dashboard . forEach (( item ) => {
const status = item . achieved ? '✓ Achieved!' : ` ${ item . progress } %` ;
console . log ( ` ${ item . exercise } : ${ item . current } / ${ item . goal } lbs ( ${ status } )` );
});
Deleting a Goal
import { getGoalWeights , saveGoalWeights } from '@/lib/storage' ;
async function deleteGoal ( exerciseName : string ) {
const goals = await getGoalWeights ();
delete goals [ exerciseName ];
await saveGoalWeights ( goals );
}
// Usage
await deleteGoal ( 'Squat' );
Goal Validation
import { setGoalWeight , getGoalWeight } from '@/lib/storage' ;
async function setValidatedGoal ( exerciseName : string , weight : number ) {
// Validation rules
if ( weight <= 0 ) {
throw new Error ( 'Goal weight must be positive' );
}
if ( weight > 1000 ) {
throw new Error ( 'Goal weight seems unrealistic' );
}
// Check if goal is lower than current
const current = await getCurrentMaxWeight ( exerciseName );
if ( current && weight < current ) {
console . warn ( `Warning: Goal ( ${ weight } ) is lower than current max ( ${ current } )` );
}
await setGoalWeight ( exerciseName , weight );
}
Best Practices
Use consistent exercise names
Goal weights are keyed by exercise name. Ensure exercise names match exactly between your exercise library and goal storage. // Good - consistent naming
await setGoalWeight ( 'Squat' , 315 );
const goal = await getGoalWeight ( 'Squat' ); // Found
// Bad - inconsistent naming
await setGoalWeight ( 'Squat' , 315 );
const goal = await getGoalWeight ( 'squat' ); // null
Set realistic, progressive goals
Goals should be challenging but achievable within the 16-week program timeline. // Calculate recommended goal based on current max
const currentMax = 225 ;
const recommendedGoal = currentMax * 1.2 ; // 20% increase
await setGoalWeight ( 'Squat' , recommendedGoal );
Track goal progress regularly
Compare goal weights against recent workout performance to stay motivated. // Weekly progress check
async function weeklyGoalCheck () {
const dashboard = await getGoalsDashboard ();
const onTrack = dashboard . filter ( g => g . progress >= 50 );
console . log ( ` ${ onTrack . length } of ${ dashboard . length } goals on track` );
}
getExercises Load exercises to set goals for
getLoggedWorkouts Track progress toward goals