Getting A better Log Entry Experience, and history setup
This commit is contained in:
parent
98a86ca6a8
commit
5d3396c333
15 changed files with 428 additions and 140 deletions
84
Tracking.md
Normal file
84
Tracking.md
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
Aerobic:
|
||||||
|
- Resting Heart Rate (RHR)
|
||||||
|
- Elevated Heart Rate (EHR)
|
||||||
|
- Recovery Time (Elevated to Resting)
|
||||||
|
- VO2 (Oxygenation during exercise)
|
||||||
|
- Pace / Speed (distance per time)
|
||||||
|
- Total Time per session
|
||||||
|
- Exercise Type
|
||||||
|
- Trends through
|
||||||
|
- Pace / Speed over Time (weekly, monthly, etc)
|
||||||
|
- Weekly Duration (total time in aerobic exercise per week)
|
||||||
|
- Exercise Difficulty Rating (EDR) - Subjective 1 - 10 scale
|
||||||
|
- Resting Heart Rate over time
|
||||||
|
- Recovery Time over time
|
||||||
|
|
||||||
|
Weight trainng:
|
||||||
|
- Exercise Type
|
||||||
|
- Max Day / Regular Training
|
||||||
|
- Weight used
|
||||||
|
- Sets done
|
||||||
|
- Repetitions completed
|
||||||
|
- Half Repetitions completed
|
||||||
|
- To failure (true/false)
|
||||||
|
- Trends through
|
||||||
|
- Weight per exercise type over time
|
||||||
|
- Sets done per weight level per exercise type over time
|
||||||
|
- Reps done per set per weight level per exercise type over time
|
||||||
|
- Body part measurements (inches / centimeters)
|
||||||
|
- Max Lift on Max Days
|
||||||
|
- Max Lift Reps
|
||||||
|
|
||||||
|
Meal Tracking
|
||||||
|
- Meal Name
|
||||||
|
- Dishes included in Meal
|
||||||
|
- Approximate portion size
|
||||||
|
- Approximate calories
|
||||||
|
- Approxmiate portein in grams
|
||||||
|
- Approximate fat content in grams / calories
|
||||||
|
- Trends through
|
||||||
|
- Personal Goal (more calories or less?)
|
||||||
|
- Number of meals per day
|
||||||
|
- Calorie count
|
||||||
|
- Protein gram count
|
||||||
|
- Fat gram / calorie count
|
||||||
|
|
||||||
|
routine {
|
||||||
|
_id: routineId,
|
||||||
|
name: routine_name,
|
||||||
|
type: routine_type,
|
||||||
|
addedBy: user,
|
||||||
|
addedDate: yyyy-mm-dd,
|
||||||
|
addedTime: hh:mm:ss,
|
||||||
|
}
|
||||||
|
|
||||||
|
exercises {
|
||||||
|
_id: exerciseId,
|
||||||
|
routineId: routineId,
|
||||||
|
exName: exercise_name,
|
||||||
|
exercise_type: exercise_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
logEntry {
|
||||||
|
_id: logId,
|
||||||
|
routineId: routineId,
|
||||||
|
exerciseId: exerciseId,
|
||||||
|
"date": "2023-03-01",
|
||||||
|
"exercises": [
|
||||||
|
{
|
||||||
|
"name": "Bench Press",
|
||||||
|
"weight": 120,
|
||||||
|
"sets": [
|
||||||
|
{
|
||||||
|
"reps": 8,
|
||||||
|
"went_to_failure": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reps": 10,
|
||||||
|
"went_to_failure": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sets_performed": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -6,25 +6,23 @@
|
||||||
<header>
|
<header>
|
||||||
<h3>Workouts</h3>
|
<h3>Workouts</h3>
|
||||||
</header>
|
</header>
|
||||||
<div role="group">
|
<div role="group" class="infoBody" id="workoutData">
|
||||||
<div>
|
<div>
|
||||||
<h4>Workouts</h4>
|
<h4>{{workoutCount}} Workout Routines</h4>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
{{workoutCount}}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div role="group">
|
<div role="group">
|
||||||
<div>
|
<div>
|
||||||
<h4>Exercise Logs</h4>
|
<h4>{{logCount}} Exercise Logs</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer role="group">
|
||||||
|
<div>
|
||||||
|
<a href="#!" id="workoutData"><i class="material-icons">chart</i> Workout History</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{logCount}}
|
<a href="#!" id="logWorkout"><i class="material-icons">notes</i> Log a Workout</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
<a href="#!" id="logWorkout"><i class="material-icons">notes</i> Log a Workout</a>
|
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,7 @@ Template.home.events({
|
||||||
'click #logMeasure' (e) {
|
'click #logMeasure' (e) {
|
||||||
FlowRouter.go('/measLogEntry');
|
FlowRouter.go('/measLogEntry');
|
||||||
},
|
},
|
||||||
|
'click #workoutData' (e) {
|
||||||
|
FlowRouter.go('/workoutData');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -39,7 +39,6 @@ Template.measLogEntry.events({
|
||||||
if (!measInfo) {
|
if (!measInfo) {
|
||||||
console.log(" UNABLE to find measurement info.");
|
console.log(" UNABLE to find measurement info.");
|
||||||
} else {
|
} else {
|
||||||
console.dir(measInfo);
|
|
||||||
let measure1 = $("#" + measInfo.measurementName).val();
|
let measure1 = $("#" + measInfo.measurementName).val();
|
||||||
let measureName = measInfo.measurementName;
|
let measureName = measInfo.measurementName;
|
||||||
let units = measInfo.measurementUnits;
|
let units = measInfo.measurementUnits;
|
||||||
|
|
|
||||||
|
|
@ -5,63 +5,91 @@
|
||||||
<select name="selectExerciseToLog" class="selectExerciseToLog" id="selectExerciseToLog">
|
<select name="selectExerciseToLog" class="selectExerciseToLog" id="selectExerciseToLog">
|
||||||
<option value="" disabled selected> + Add Log Entry</option>
|
<option value="" disabled selected> + Add Log Entry</option>
|
||||||
{{#each workoutLog}}
|
{{#each workoutLog}}
|
||||||
<option value="{{_id}}">{{exerciseName}}</option>
|
<option value="{{_id}} | {{exerciseName}}">{{exerciseName}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if $eq exIdSelected true}}
|
{{#if $eq exIdSelected true}}
|
||||||
<!-- add fields for log based on selection from drop button above -->
|
<div class="grid">
|
||||||
<div class="grid">
|
{{#if $eq logIdSet false}}
|
||||||
<div>
|
<div>
|
||||||
<h3>{{exerciseToLog.exerciseName}}</h3>
|
<input type="number" class="exerciseWeight" id="exerciseWeight" placeholder="Enter Weight..." />
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div>
|
||||||
|
<h4>{{enteredWeight}}</h4>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div>
|
||||||
|
<button class="outline addASet" id="addASet">+ Add a Set</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{#if $eq addSet true}}
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div>
|
<div>
|
||||||
<label>{{exerciseToLog.exerciseMeasure}}</label>
|
<input type="number" class="addRepsVal" id="addRepsVal_{{ setNo }}">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="number" id="{{exerciseToLog.exerciseMeasure}}" />
|
<button class="saveSet secondary" id="saveSet">Save Set</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</div>
|
||||||
<label>{{exerciseToLog.exerciseUnitMeasure}}</label>
|
{{/if}}
|
||||||
</div>
|
|
||||||
</div>
|
<table>
|
||||||
<hr>
|
<thead>
|
||||||
<div class="grid">
|
<tr>
|
||||||
{{#if $neq exerciseToLog.exerciseMeasure2 ""}}
|
<th>Set #</th>
|
||||||
<div>
|
<th>Reps</th>
|
||||||
<label>{{exerciseToLog.exerciseMeasure2}}</label>
|
</tr>
|
||||||
</div>
|
</thead>
|
||||||
<div>
|
<tbody>
|
||||||
<input type="number" id="{{exerciseToLog.exerciseMeasure2}}" />
|
{{#each setsRecorded}}
|
||||||
</div>
|
<tr>
|
||||||
<div>
|
<td>{{setNumber}}</td>
|
||||||
{{exerciseToLog.exerciseUnitMeasure2}}
|
<td>{{repCount}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{#if $neq prevWorkout false}}
|
||||||
|
<hr>
|
||||||
|
<div class="article">
|
||||||
|
<header>Last Workout on {{prevWorkout.dateAdded}}</header>
|
||||||
|
<table class="striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Weight</th>
|
||||||
|
<th>Sets</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{{prevWorkout.exerciseWeight}}</td>
|
||||||
|
<td>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Set #</th>
|
||||||
|
<th>Reps</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each prevWorkout.sets}}
|
||||||
|
<tr>
|
||||||
|
<td>{{setNumber}}</td>
|
||||||
|
<td>{{repCount}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="grid">
|
|
||||||
{{#if $neq exerciseToLog.exerciseMeasure3 ""}}
|
|
||||||
<div>
|
|
||||||
<label>{{exerciseToLog.exerciseMeasure3}}</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<input type="number" id="{{exerciseToLog.exerciseMeasure3}}" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{exerciseToLog.exerciseUnitMeasure3}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
<div class="grid">
|
|
||||||
<div>
|
|
||||||
<button class="primary saveLogEntry right" id="saveLogEntry">Save</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{> snackbar}}
|
{{> snackbar}}
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -2,6 +2,7 @@ import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
|
||||||
import { Workouts } from '../../../../imports/api/workouts';
|
import { Workouts } from '../../../../imports/api/workouts';
|
||||||
import { WorkoutLog } from '../../../../imports/api/workoutLog';
|
import { WorkoutLog } from '../../../../imports/api/workoutLog';
|
||||||
import { LogEntry } from '../../../../imports/api/logEntry';
|
import { LogEntry } from '../../../../imports/api/logEntry';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
Template.logEntry.onCreated(function() {
|
Template.logEntry.onCreated(function() {
|
||||||
this.subscribe("myWorkoutRoutines");
|
this.subscribe("myWorkoutRoutines");
|
||||||
|
|
@ -12,6 +13,9 @@ Template.logEntry.onCreated(function() {
|
||||||
Template.logEntry.onRendered(function() {
|
Template.logEntry.onRendered(function() {
|
||||||
Session.set("exId", "");
|
Session.set("exId", "");
|
||||||
Session.set("exIdSelected", false);
|
Session.set("exIdSelected", false);
|
||||||
|
Session.set("setNo", 0);
|
||||||
|
Session.set("addSet", false);
|
||||||
|
Session.set("logId", "f");
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.logEntry.helpers({
|
Template.logEntry.helpers({
|
||||||
|
|
@ -24,70 +28,121 @@ Template.logEntry.helpers({
|
||||||
},
|
},
|
||||||
exIdSelected: function() {
|
exIdSelected: function() {
|
||||||
return Session.get("exIdSelected");
|
return Session.get("exIdSelected");
|
||||||
}
|
},
|
||||||
|
setNo: function() {
|
||||||
|
return Session.get("setNo");
|
||||||
|
},
|
||||||
|
addSet: function() {
|
||||||
|
return Session.get("addSet");
|
||||||
|
},
|
||||||
|
setsRecorded: async() => {
|
||||||
|
let logId = Session.get("logId");
|
||||||
|
const logInfo = await LogEntry.findOneAsync({ _id: logId });
|
||||||
|
|
||||||
|
if (logInfo) {
|
||||||
|
return logInfo && logInfo.sets ? logInfo.sets : [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logIdSet: function() {
|
||||||
|
let logId = Session.get("logId");
|
||||||
|
if (logId != "f") {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enteredWeight: function() {
|
||||||
|
return Session.get("enteredWeight");
|
||||||
|
},
|
||||||
|
prevWorkout: async() => {
|
||||||
|
let exerciseName = Session.get("exerciseName");
|
||||||
|
let logs = await LogEntry.findOneAsync({ exerciseName: exerciseName }, { sort: { _id: -1 } });
|
||||||
|
let todayDateTime = new Date();
|
||||||
|
let today = dayjs(todayDateTime).format('YYYY-MM-DD');
|
||||||
|
if (logs) {
|
||||||
|
if (logs.dateAdded != today) {
|
||||||
|
return logs;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.logEntry.events({
|
Template.logEntry.events({
|
||||||
'change #selectExerciseToLog' (e) {
|
'change #selectExerciseToLog' (e) {
|
||||||
let exerciseId = $("#selectExerciseToLog").val();
|
let exerciseNameAndId = $("#selectExerciseToLog").val();
|
||||||
|
let splitExNameId = exerciseNameAndId.split(' | ');
|
||||||
|
let exerciseId = splitExNameId[0];
|
||||||
|
let exerciseName = splitExNameId[1];
|
||||||
|
|
||||||
|
Session.set("setNo", 0);
|
||||||
|
Session.set("exerciseName", exerciseName);
|
||||||
Session.set("exerciseLogId", exerciseId);
|
Session.set("exerciseLogId", exerciseId);
|
||||||
Session.set("exIdSelected", true);
|
Session.set("exIdSelected", true);
|
||||||
|
Session.set("logId", "f");
|
||||||
},
|
},
|
||||||
'click #saveLogEntry' (e) {
|
'click #addASet' (e) {
|
||||||
let logId = Session.get("exerciseLogId");
|
let setNo = Session.get("setNo");
|
||||||
|
let logId = Session.get("logId");
|
||||||
|
setNo = setNo+=1;
|
||||||
|
Session.set("setNo", setNo);
|
||||||
|
Session.set("addSet", true);
|
||||||
|
let exerciseNameAndId = $("#selectExerciseToLog").val();
|
||||||
|
let splitExNameId = exerciseNameAndId.split(' | ');
|
||||||
|
let exerciseId = splitExNameId[0];
|
||||||
|
let exerciseName = splitExNameId[1];
|
||||||
|
let weight = $("#exerciseWeight").val();
|
||||||
|
let weightNo = Number(weight);
|
||||||
|
|
||||||
const getRoutine = async() => {
|
|
||||||
let workout = await WorkoutLog.findOneAsync({ _id: logId });
|
|
||||||
|
|
||||||
if (!workout) {
|
if (logId == "f") {
|
||||||
console.log("no workout found.");
|
Session.set('enteredWeight', weight);
|
||||||
} else {
|
const addLogEntry = async() => {
|
||||||
let routineId = workout.routineId;
|
try {
|
||||||
let exerName = workout.exerciseName;
|
const result = await Meteor.callAsync('add.logEntry', exerciseId, exerciseName, weightNo);
|
||||||
let measure1 = $("#" + workout.exerciseMeasure).val();
|
if (!result) {
|
||||||
let measUnit1 = workout.exerciseUnitMeasure;
|
console.log(" UNABLE to add log entry.");
|
||||||
let measure2 = $("#" + workout.exerciseMeasure2).val();
|
showSnackbar("Unable to add Log Entry!", "red");
|
||||||
let measUnit2 = workout.exerciseUnitMeasure2;
|
} else {
|
||||||
let measure3 = $("#" + workout.exerciseMeasure3).val();
|
Session.set("logId", result);
|
||||||
let measUnit3 = workout.exerciseUnitMeasure3;
|
showSnackbar("Log Started!", "green");
|
||||||
let measName1 = workout.exerciseMeasure;
|
|
||||||
let measName2 = workout.exerciseMeasure2;
|
|
||||||
let measName3 = workout.exerciseMeasure3;
|
|
||||||
|
|
||||||
let meas1 = Number(measure1);
|
|
||||||
let meas2 = Number(measure2);
|
|
||||||
let meas3 = Number(measure3);
|
|
||||||
|
|
||||||
if (meas1 == "" || meas1 == null) {
|
|
||||||
showSnackbar("Measurement for " + workout.exerciseMeasure + " is required!", " red");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const saveLogEntry = async() => {
|
|
||||||
try {
|
|
||||||
const result = Meteor.callAsync('add.logEntry', routineId, logId, exerName, measName1, meas1, measUnit1, measName2, meas2, measUnit2, measName3, meas3, measUnit3);
|
|
||||||
if (!result) {
|
|
||||||
console.log(" UNABLE TO SAVE LOG ENTRY!");
|
|
||||||
showSnackbar("Unable to save log entry!", "red");
|
|
||||||
} else {
|
|
||||||
$("#" + workout.exerciseMeasure).val("");
|
|
||||||
$("#" + workout.exerciseMeasure2).val("");
|
|
||||||
$("#" + workout.exerciseMeasure3).val("");
|
|
||||||
$("#selectExerciseToLog").val("");
|
|
||||||
Session.set("exIdSelected", false);
|
|
||||||
Session.set("exerciseLogId", "");
|
|
||||||
showSnackbar("Log Entry Added!", "green");
|
|
||||||
}
|
|
||||||
} catch(error) {
|
|
||||||
console.log(" ERROR saving log entry: " + error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
saveLogEntry();
|
} catch (error) {
|
||||||
|
console.log(" ERROR adding log entry: " + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addLogEntry();
|
||||||
}
|
}
|
||||||
getRoutine();
|
},
|
||||||
|
'click #saveSet' (e) {
|
||||||
|
let logId = Session.get("logId");
|
||||||
|
let setNo = Session.get("setNo");
|
||||||
|
let reps = $("#addRepsVal_" + setNo).val();
|
||||||
|
|
||||||
|
let sets = Number(setNo);
|
||||||
|
let repCount = Number(reps);
|
||||||
|
|
||||||
}
|
// add meteor call to add this set to the log entry.
|
||||||
|
const addSetToLog = async() => {
|
||||||
|
try {
|
||||||
|
const result = await Meteor.callAsync('add.setToLog', logId, sets, repCount);
|
||||||
|
if (!result) {
|
||||||
|
console.log(" UNABLE to add set to log entry.");
|
||||||
|
showSnackbar("Set NOT added to log!", "red");
|
||||||
|
} else {
|
||||||
|
showSnackbar("Set Added Successfully!", "green");
|
||||||
|
$("#addRepsVal_" + setNo).val("");
|
||||||
|
Session.set("addSet", false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(" ERROR adding set to log entry: " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addSetToLog();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
34
client/General/Workouts/Workoutdata/workoutData.js
Normal file
34
client/General/Workouts/Workoutdata/workoutData.js
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
|
||||||
|
import { Workouts } from '../../../../imports/api/workouts';
|
||||||
|
import { WorkoutLog } from '../../../../imports/api/workoutLog';
|
||||||
|
import { LogEntry } from '../../../../imports/api/logEntry';
|
||||||
|
import { Chart } from 'chart.js';
|
||||||
|
import { dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
Template.workoutData.onCreated(function() {
|
||||||
|
this.subscribe("myWorkoutRoutines");
|
||||||
|
this.subscribe("myWorkoutLog");
|
||||||
|
this.subscribe("myLogEntries");
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.workoutData.onRendered(function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.workoutData.helpers({
|
||||||
|
workoutLog: function() {
|
||||||
|
return WorkoutLog.find({});
|
||||||
|
},
|
||||||
|
lastWorkout: async() => {
|
||||||
|
const mostRecentDate = await LogEntry.findOneAsync({}, { sort: { dateAdded: -1 } });
|
||||||
|
if (mostRecentDate) {
|
||||||
|
return LogEntry.find({ dateAdded: mostRecentDate.dateAdded });
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.workoutData.events({
|
||||||
|
|
||||||
|
});
|
||||||
45
client/General/Workouts/Workoutdata/workoutdata.html
Normal file
45
client/General/Workouts/Workoutdata/workoutdata.html
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
<template name="workoutData">
|
||||||
|
<h1>Workouts</h1>
|
||||||
|
<ul class="collection">
|
||||||
|
<li class="collection-header">Last Workout</li>
|
||||||
|
|
||||||
|
<li class="collection-item">
|
||||||
|
<table class="striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Exercise</th>
|
||||||
|
<th>Weight</th>
|
||||||
|
<th>Sets</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each lastWorkout}}
|
||||||
|
<tr>
|
||||||
|
<td>{{exerciseName}}</td>
|
||||||
|
<td>{{exerciseWeight}}</td>
|
||||||
|
<td>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Sets</th>
|
||||||
|
<th>Reps</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each sets}}
|
||||||
|
<tr>
|
||||||
|
<td>{{setNumber}}</td>
|
||||||
|
<td>{{repCount}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{{#if currentUser}}
|
{{#if currentUser}}
|
||||||
{{#if isInRole "systemadmin"}}
|
{{#if isInRole "systemadmin"}}
|
||||||
<li><a href="#" id="manage" class="navBtn">Manage</a></li>
|
<li><a href="#" id="systemAdmin" class="navBtn">Manage</a></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<li><a href="#!" id="home" class="navBtn">Home</a></li>
|
<li><a href="#!" id="home" class="navBtn">Home</a></li>
|
||||||
<li><a href="#!" id="logEntry" class="navBtn">Log Entry</a></li>
|
<li><a href="#!" id="logEntry" class="navBtn">Log Entry</a></li>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template name="MainLayout">
|
<template name="MainLayout">
|
||||||
{{#if Template.subscriptionsReady}}
|
{{#if Template.subscriptionsReady}}
|
||||||
<div class="container">
|
<div class="container-fluid">
|
||||||
{{> headerBar}}
|
{{> headerBar}}
|
||||||
{{> Template.dynamic template=main}}
|
{{> Template.dynamic template=main}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collection-item:hover {
|
/* .collection-item:hover {
|
||||||
background-color: #282828
|
background-color: #282828
|
||||||
}
|
} */
|
||||||
|
|
||||||
/* Remove bottom border from last item */
|
/* Remove bottom border from last item */
|
||||||
.collection-item:last-child {
|
.collection-item:last-child {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { Mongo } from 'meteor/mongo';
|
import { Mongo } from 'meteor/mongo';
|
||||||
import { check } from 'meteor/check';
|
import { check } from 'meteor/check';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
export const LogEntry = new Mongo.Collection('logEntry');
|
export const LogEntry = new Mongo.Collection('logEntry');
|
||||||
|
|
||||||
|
|
@ -12,39 +13,45 @@ LogEntry.allow({
|
||||||
});
|
});
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
async 'add.logEntry' (routineId, logId, exerciseName, measName1, measure1, measUnit1, measName2, measure2, measUnit2, measName3, measure3, measUnit3) {
|
async 'add.logEntry' (exerciseId, exerciseName, exerciseWeight) {
|
||||||
check(routineId, String);
|
check(exerciseId, String);
|
||||||
check(logId, String);
|
|
||||||
check(exerciseName, String);
|
check(exerciseName, String);
|
||||||
check(measName1, String);
|
check(exerciseWeight, Number);
|
||||||
check(measure1, Number);
|
|
||||||
check(measUnit1, String);
|
|
||||||
check(measName2, String);
|
|
||||||
check(measure2, Number);
|
|
||||||
check(measUnit2, String);
|
|
||||||
check(measName3, String);
|
|
||||||
check(measure3, Number);
|
|
||||||
check(measUnit3, String);
|
|
||||||
|
|
||||||
if (!this.userId) {
|
if (!this.userId) {
|
||||||
throw new Meteor.Error('You are not allowed to add log entries. Make sure you are logged in with valid user credentials.');
|
throw new Meteor.Error('You are not allowed to add log entries. Make sure you are logged in with valid user credentials.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rightNow = new Date();
|
||||||
|
let dateAdded = dayjs(rightNow).format('YYYY-MM-DD');
|
||||||
|
let timeAdded = dayjs(rightNow).format("HH:MM:SS");
|
||||||
|
|
||||||
return await LogEntry.insertAsync({
|
return await LogEntry.insertAsync({
|
||||||
routineId: routineId,
|
exerciseId: exerciseId,
|
||||||
logId: logId,
|
|
||||||
exerciseName: exerciseName,
|
exerciseName: exerciseName,
|
||||||
measName1: measName1,
|
exerciseWeight: exerciseWeight,
|
||||||
measure1: measure1,
|
dateAdded: dateAdded,
|
||||||
measUnit1: measUnit1,
|
timeAdded: timeAdded,
|
||||||
measName2: measName2,
|
|
||||||
measrue2: measure2,
|
|
||||||
measUnit2: measUnit2,
|
|
||||||
measName3: measName3,
|
|
||||||
measure3: measure3,
|
|
||||||
measUnit3: measUnit3,
|
|
||||||
addedBy: this.userId,
|
addedBy: this.userId,
|
||||||
addedOn: new Date()
|
});
|
||||||
|
},
|
||||||
|
async 'add.setToLog' (logId, setNo, repCount) {
|
||||||
|
check(logId, String);
|
||||||
|
check(setNo, Number);
|
||||||
|
check(repCount, Number);
|
||||||
|
|
||||||
|
if (!this.userId) {
|
||||||
|
throw new Meteor.Error('You are not allowed to add sets to log entries. Make sure you are logged in with valid user credentials.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return await LogEntry.updateAsync({ _id: logId }, {
|
||||||
|
$addToSet: {
|
||||||
|
sets:
|
||||||
|
{
|
||||||
|
setNumber: setNo,
|
||||||
|
repCount: repCount,
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -103,4 +103,11 @@ FlowRouter.route('/measLogEntry', {
|
||||||
action() {
|
action() {
|
||||||
this.render('MainLayout', { main: 'measLogEntry'});
|
this.render('MainLayout', { main: 'measLogEntry'});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FlowRouter.route('/workoutData', {
|
||||||
|
name: 'workoutData',
|
||||||
|
action() {
|
||||||
|
this.render('MainLayout', { main: 'workoutData'});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
26
package-lock.json
generated
26
package-lock.json
generated
|
|
@ -7,6 +7,8 @@
|
||||||
"name": "meteor-app",
|
"name": "meteor-app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.17.9",
|
"@babel/runtime": "^7.17.9",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
|
"dayjs": "^1.11.19",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"meteor-node-stubs": "^1.2.1",
|
"meteor-node-stubs": "^1.2.1",
|
||||||
"node-cron": "^3.0.3",
|
"node-cron": "^3.0.3",
|
||||||
|
|
@ -25,6 +27,12 @@
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@kurkle/color": {
|
||||||
|
"version": "0.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
|
||||||
|
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/addressparser": {
|
"node_modules/addressparser": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
|
||||||
|
|
@ -107,6 +115,18 @@
|
||||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/chart.js": {
|
||||||
|
"version": "4.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz",
|
||||||
|
"integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@kurkle/color": "^0.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"pnpm": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
|
@ -137,6 +157,12 @@
|
||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
|
||||||
|
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/delayed-stream": {
|
"node_modules/delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.17.9",
|
"@babel/runtime": "^7.17.9",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
|
"dayjs": "^1.11.19",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"meteor-node-stubs": "^1.2.1",
|
"meteor-node-stubs": "^1.2.1",
|
||||||
"node-cron": "^3.0.3",
|
"node-cron": "^3.0.3",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue