Making improvements

This commit is contained in:
Brian McGonagill 2026-02-04 17:05:47 -06:00
parent 78e0e82449
commit dd7e4a4933
11 changed files with 349 additions and 52 deletions

View file

@ -6,18 +6,18 @@
meteor-base@1.5.2 # Packages every Meteor app needs to have meteor-base@1.5.2 # Packages every Meteor app needs to have
mobile-experience@1.1.2 # Packages for a great mobile UX mobile-experience@1.1.2 # Packages for a great mobile UX
mongo@2.1.4 # The database Meteor supports right now mongo@2.2.0 # The database Meteor supports right now
blaze-html-templates # Compile .html files into Meteor Blaze views blaze-html-templates # Compile .html files into Meteor Blaze views
jquery # Wrapper package for npm-installed jquery jquery # Wrapper package for npm-installed jquery
reactive-var@1.0.13 # Reactive variable for tracker reactive-var@1.0.13 # Reactive variable for tracker
tracker@1.3.4 # Meteor's client-side reactive programming library tracker@1.3.4 # Meteor's client-side reactive programming library
standard-minifier-css@1.9.3 # CSS minifier run for production mode standard-minifier-css@1.10.0 # CSS minifier run for production mode
standard-minifier-js@3.1.1 # JS minifier run for production mode standard-minifier-js@3.2.0 # JS minifier run for production mode
es5-shim@4.8.1 # ECMAScript 5 compatibility for older browsers es5-shim@4.8.1 # ECMAScript 5 compatibility for older browsers
ecmascript@0.16.13 # Enable ECMAScript2015+ syntax in app code ecmascript@0.17.0 # Enable ECMAScript2015+ syntax in app code
typescript@5.6.6 # Enable TypeScript syntax in .ts and .tsx modules typescript@5.9.3 # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.6.2 # Server-side component of the `meteor shell` command shell-server@0.7.0 # Server-side component of the `meteor shell` command
@ -27,6 +27,6 @@ blaze-hot # Update files using Blaze's API with HMR
session@1.2.2 session@1.2.2
ostrio:flow-router-extra ostrio:flow-router-extra
email@3.1.2 email@3.1.2
accounts-password@3.2.1 accounts-password@3.2.2
roles@1.0.1 roles@1.0.1
arianjahiri:meteor-handlebars-helpers arianjahiri:meteor-handlebars-helpers

View file

@ -1 +1 @@
METEOR@3.3.2 METEOR@3.4

View file

@ -1,9 +1,9 @@
accounts-base@3.1.2 accounts-base@3.2.0
accounts-password@3.2.1 accounts-password@3.2.2
allow-deny@2.1.0 allow-deny@2.1.0
arianjahiri:meteor-handlebars-helpers@0.0.1 arianjahiri:meteor-handlebars-helpers@0.0.1
autoupdate@2.0.1 autoupdate@2.0.1
babel-compiler@7.12.2 babel-compiler@7.13.0
babel-runtime@1.5.2 babel-runtime@1.5.2
base64@1.0.13 base64@1.0.13
binary-heap@1.0.12 binary-heap@1.0.12
@ -11,11 +11,11 @@ blaze@3.0.2
blaze-hot@2.0.0 blaze-hot@2.0.0
blaze-html-templates@3.0.0 blaze-html-templates@3.0.0
blaze-tools@2.0.0 blaze-tools@2.0.0
boilerplate-generator@2.0.2 boilerplate-generator@2.1.0
caching-compiler@2.0.1 caching-compiler@2.0.1
caching-html-compiler@2.0.0 caching-html-compiler@2.0.0
callback-hook@1.6.1 callback-hook@1.6.1
check@1.4.4 check@1.5.0
core-runtime@1.0.0 core-runtime@1.0.0
ddp@1.4.2 ddp@1.4.2
ddp-client@3.1.1 ddp-client@3.1.1
@ -25,7 +25,7 @@ ddp-server@3.1.2
deps@1.0.5-pre.1 deps@1.0.5-pre.1
diff-sequence@1.1.3 diff-sequence@1.1.3
dynamic-import@0.7.4 dynamic-import@0.7.4
ecmascript@0.16.13 ecmascript@0.17.0
ecmascript-runtime@0.8.3 ecmascript-runtime@0.8.3
ecmascript-runtime-client@0.12.3 ecmascript-runtime-client@0.12.3
ecmascript-runtime-server@0.11.1 ecmascript-runtime-server@0.11.1
@ -45,18 +45,18 @@ jquery@3.0.2
launch-screen@2.0.1 launch-screen@2.0.1
localstorage@1.2.1 localstorage@1.2.1
logging@1.3.6 logging@1.3.6
meteor@2.1.1 meteor@2.2.0
meteor-base@1.5.2 meteor-base@1.5.2
minifier-css@2.0.1 minifier-css@2.0.1
minifier-js@3.0.4 minifier-js@3.1.0
minimongo@2.0.4 minimongo@2.0.5
mobile-experience@1.1.2 mobile-experience@1.1.2
mobile-status-bar@1.1.1 mobile-status-bar@1.1.1
modern-browsers@0.2.3 modern-browsers@0.2.3
modules@0.20.3 modules@0.20.3
modules-runtime@0.13.2 modules-runtime@0.13.2
modules-runtime-hot@0.14.3 modules-runtime-hot@0.14.3
mongo@2.1.4 mongo@2.2.0
mongo-decimal@0.2.0 mongo-decimal@0.2.0
mongo-dev-server@1.1.1 mongo-dev-server@1.1.1
mongo-id@1.0.9 mongo-id@1.0.9
@ -67,7 +67,7 @@ ostrio:flow-router-extra@3.12.1
promise@1.0.0 promise@1.0.0
random@1.2.2 random@1.2.2
rate-limit@1.1.2 rate-limit@1.1.2
react-fast-refresh@0.2.9 react-fast-refresh@0.3.0
reactive-dict@1.3.2 reactive-dict@1.3.2
reactive-var@1.0.13 reactive-var@1.0.13
reload@1.3.2 reload@1.3.2
@ -76,19 +76,19 @@ roles@1.0.1
routepolicy@1.1.2 routepolicy@1.1.2
session@1.2.2 session@1.2.2
sha@1.0.10 sha@1.0.10
shell-server@0.6.2 shell-server@0.7.0
socket-stream-client@0.6.1 socket-stream-client@0.6.1
spacebars@2.0.0 spacebars@2.0.0
spacebars-compiler@2.0.0 spacebars-compiler@2.0.0
standard-minifier-css@1.9.3 standard-minifier-css@1.10.0
standard-minifier-js@3.1.1 standard-minifier-js@3.2.0
templating@1.4.4 templating@1.4.4
templating-compiler@2.0.0 templating-compiler@2.0.0
templating-runtime@2.0.1 templating-runtime@2.0.1
templating-tools@2.0.0 templating-tools@2.0.0
tracker@1.3.4 tracker@1.3.4
typescript@5.6.6 typescript@5.9.3
underscore@1.6.4 underscore@1.6.4
url@1.3.5 url@1.3.5
webapp@2.0.7 webapp@2.1.0
webapp-hashing@1.1.2 webapp-hashing@1.1.2

View file

@ -1,12 +1,36 @@
# This is a template to get started. # Open Health
The template includes Workout Routines
- Registration - Routine Name
- Login / Authentication with username / password - Exercise Type
- First person to register is the System Admin role and has full control over the installation. - Aerobic
- Initial roles are - Strength
- systemadmin - Flexibility
- tenantadmin (admin over a single tenant) - Endurance
- user (non administrative role) - Exercise Measure
- Distance
- Weight
- Time
- Rate
- Exercise Units
- Distance
- Miles
- Kilometers
- Meters
- Yards
- Feet
- Weight
- KG
- LBS
- Time
- Hours
- Minutes
- Seconds
- Milliseconds
- Rate
- Miles per Hour
- Kilometers per Hour
- Beats Per Minute
- Steps per Minute
- Instructions
There are a few things built in already, like placeholders for the Site Name, App Name, etc, but the rest is a blank slate.

View file

@ -1,5 +1,174 @@
<template name="workoutLog"> <template name="workoutLog">
<h1>Workout Log</h1> <h1>Create Workout Log</h1>
<h2>{{routineName}}</h2> <h2>{{routine.routineName}}</h2>
<br>
<div class="grid">
<div>
<label for="exerciseName">Exercise Name</label>
<input type="text" class="exerciseName" id="exerciseName" required />
</div>
<div>
<label for="exerciseType">Exercise Type</label>
<select name="exerciseType" id="exerciseType" class="exerciseType">
<option value="" disabled selected>Choose ...</option>
<option value="Aerobic">Aerobic</option>
<option value="Endurance">Endurance</option>
<option value="Flexibility">Flexibility</option>
<option value="Strength">Strength</option>
</select>
</div>
</div>
<div class="grid">
<div>
<label for="exerciseMeasure">Exercise Measurement</label>
<select name="exerciseMeasure" id="exerciseMeasure">
<option value="" disabled selected>Choose ...</option>
<option value="Disatance">Distance</option>
<option value="Rate">Rate</option>
<option value="Time">Time</option>
<option value="Weight">Weight</option>
<option value="Reps">Reps</option>
<option value="Sets">Sets</option>
</select>
</div>
<div>
<label for="exerciseUnitMeasure">Measruement Unit 1</label>
<select name="exerciseUnitMeasure" id="exerciseUnitMeasure">
<option value="" disabled selected>Choose ...</option>
{{#if $eq exMeas1 "Disatance"}}
<option value="Miles">Miles</option>
<option value="Kilometers">Kilometers</option>
<option value="Meters">Meters</option>
<option value="Yards">Yards</option>
<option value="Feet">Feet</option>
{{/if}}
{{#if $eq exMeas1 "Weight"}}
<option value="Kilograms">Kilograms</option>
<option value="Pounds">Pounds</option>
{{/if}}
{{#if $eq exMeas1 "Time"}}
<option value="Hours">Hours</option>
<option value="Minutes">Minutes</option>
<option value="Seconds">Seconds</option>
<option value="Milliseconds">Milliseconds</option>
{{/if}}
{{#if $eq exMeas1 "Rate"}}
<option value="Kilometers per Hour">Kilometers per Hour</option>
<option value="Miles per Hour">Miles per Hour</option>
<option value="Beats per Minute">Beats per Minute</option>
<option value="Steps per Hour">Steps per Hour</option>
<option value="Steps per Minute">Steps per Minute</option>
{{/if}}
{{#if $eq exMeas1 "Sets"}}
<option value="Count">Count</option>
{{/if}}
</select>
</div>
</div>
<div class="grid">
<div>
<label for="exerciseMeasure2">Exercise Measurement 2</label>
<select name="exerciseMeasure2" id="exerciseMeasure2">
<option value="" disabled selected>Choose ...</option>
<option value="Disatance">Distance</option>
<option value="Rate">Rate</option>
<option value="Time">Time</option>
<option value="Weight">Weight</option>
<option value="Reps">Reps</option>
<option value="Sets">Sets</option>
</select>
</div>
<div>
<label for="exerciseUnitMeasure2">Measruement Unit 2</label>
<select name="exerciseUnitMeasure2" id="exerciseUnitMeasure2">
<option value="" disabled selected>Choose ...</option>
{{#if $eq exMeas2 "Disatance"}}
<option value="Miles">Miles</option>
<option value="Kilometers">Kilometers</option>
<option value="Meters">Meters</option>
<option value="Yards">Yards</option>
<option value="Feet">Feet</option>
{{/if}}
{{#if $eq exMeas2 "Weight"}}
<option value="Kilograms">Kilograms</option>
<option value="Pounds">Pounds</option>
{{/if}}
{{#if $eq exMeas2 "Time"}}
<option value="Hours">Hours</option>
<option value="Minutes">Minutes</option>
<option value="Seconds">Seconds</option>
<option value="Milliseconds">Milliseconds</option>
{{/if}}
{{#if $eq exMeas2 "Rate"}}
<option value="Kilometers per Hour">Kilometers per Hour</option>
<option value="Miles per Hour">Miles per Hour</option>
<option value="Beats per Minute">Beats per Minute</option>
<option value="Steps per Hour">Steps per Hour</option>
<option value="Steps per Minute">Steps per Minute</option>
{{/if}}
{{#if $eq exMeas2 "Sets"}}
<option value="Count">Count</option>
{{/if}}
</select>
</div>
</div>
<div class="grid">
<div>
<label for="exerciseMeasure3">Exercise Measurement 3</label>
<select name="exerciseMeasure3" id="exerciseMeasure3">
<option value="" disabled selected>Choose ...</option>
<option value="Disatance">Distance</option>
<option value="Rate">Rate</option>
<option value="Time">Time</option>
<option value="Weight">Weight</option>
<option value="Reps">Reps</option>
<option value="Sets">Sets</option>
</select>
</div>
<div>
<label for="exerciseUnitMeasure3">Measruement Unit 3</label>
<select name="exerciseUnitMeasure3" id="exerciseUnitMeasure3">
<option value="" disabled selected>Choose ...</option>
{{#if $eq exMeas3 "Disatance"}}
<option value="Miles">Miles</option>
<option value="Kilometers">Kilometers</option>
<option value="Meters">Meters</option>
<option value="Yards">Yards</option>
<option value="Feet">Feet</option>
{{/if}}
{{#if $eq exMeas3 "Weight"}}
<option value="Kilograms">Kilograms</option>
<option value="Pounds">Pounds</option>
{{/if}}
{{#if $eq exMeas3 "Time"}}
<option value="Hours">Hours</option>
<option value="Minutes">Minutes</option>
<option value="Seconds">Seconds</option>
<option value="Milliseconds">Milliseconds</option>
{{/if}}
{{#if $eq exMeas3 "Rate"}}
<option value="Kilometers per Hour">Kilometers per Hour</option>
<option value="Miles per Hour">Miles per Hour</option>
<option value="Beats per Minute">Beats per Minute</option>
<option value="Steps per Hour">Steps per Hour</option>
<option value="Steps per Minute">Steps per Minute</option>
{{/if}}
{{#if $eq exMeas3 "Sets"}}
<option value="Count">Count</option>
{{/if}}
</select>
</div>
</div>
<div class="grid">
<div>
<label for="exerciseInstruction">Instructions</label>
<textarea name="exerciseInstruction" id="exerciseInstruction"></textarea>
</div>
</div>
<div class="grid">
<div>
<button class="primary right" id="saveLogExercise">Save</button>
</div>
</div>
{{> snackbar}}
</template> </template>

View file

@ -1,18 +1,89 @@
import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import { Workouts } from '../../../imports/api/workouts.js'; import { Workouts } from '../../../../imports/api/workouts';
import { WorkoutLog } from '../../../../imports/api/workoutLog';
Template.workoutsLog.onCreated(function() { Template.workoutLog.onCreated(function() {
this.subscribe("myWorkoutRoutines"); this.subscribe("myWorkoutRoutines");
this.subscribe("myWorkoutLog");
}); });
Template.workoutsLog.onRendered(function() { Template.workoutLog.onRendered(function() {
}); });
Template.workoutsLog.helpers({ Template.workoutLog.helpers({
exMeas1: function() {
return Session.get("exMeas1");
},
exMeas2: function() {
return Session.get("exMeas2");
},
exMeas3: function() {
return Session.get("exMeas3");
},
routine: function() {
let routineId = Session.get("routineId");
let routine = Workouts.findOneAsync({ _id: routineId });
return routine;
}
}); });
Template.workoutsLog.events({ Template.workoutLog.events({
'change #exerciseMeasure, change #exerciseMeasure2, change #exerciseMeasure3' (e) {
let fieldId = e.currentTarget.id;
if (fieldId == "exerciseMeasure") {
let exMeas = $("#exerciseMeasure").val();
if (exMeas == "Sets" || exMeas == "Reps") {
exMeas = "Sets"
}
Session.set("exMeas1", exMeas);
} else if (fieldId == "exerciseMeasure2") {
let exMeas2 = $("#exerciseMeasure2").val();
if (exMeas2 == "Sets" || exMeas2 == "Reps") {
exMeas2 = "Sets"
}
Session.set("exMeas2", exMeas2);
} else {
let exMeas3 = $("#exerciseMeasure3").val();
if (exMeas3 == "Sets" || exMeas3 == "Reps") {
exMeas3 = "Sets"
}
Session.set("exMeas3", exMeas3);
}
},
'click #saveLogExercise' (e) {
let routineId = Session.get("routineId");
let exerciseName = $("#exerciseName").val();
let exerciseType = $("#exerciseType").val();
let exerciseMeasure = $("#exerciseMeasure").val();
let exerciseUnitMeasure = $("#exerciseUnitMeasure").val();
let exerciseMeasure2 = $("#exerciseMeasure2").val();
let exerciseUnitMeasure2 = $("#exerciseUnitMeasure2").val();
let exerciseMeasure3 = $("#exerciseMeasure3").val();
let exerciseUnitMeasure3 = $("#exerciseUnitMeasure3").val();
let exerciseInstruction = $("#exerciseInstruction").val();
if (typeof routineId == 'undefined' || routineId == null || routineId == "") {
showSnackbar("Unable to get Workout!", "red");
return;
} else if (exerciseName == "" || exerciseName == null) {
showSnackbar("Exercise Name is Required!", "red");
return;
} else {
const addExercise = async() => {
try {
const result = await Meteor.callAsync('add.exerciseToLog', routineId, exerciseName, exerciseType, exerciseMeasure, exerciseUnitMeasure, exerciseMeasure2, exerciseUnitMeasure2, exerciseMeasure3, exerciseUnitMeasure3, exerciseInstruction);
if (!result) {
console.log(" ISSUE saving exercise info for loggin.");
showSnackbar("Exercise Not Saved!", "red");
} else {
showSnackbar("Exercise Added!", "green");
}
} catch(error) {
console.log(" ERROR trying to add an exercise to log: " + error);
}
}
addExercise();
}
}
}); });

View file

@ -17,7 +17,7 @@
{{/if}} {{/if}}
<ul class="collection"> <ul class="collection">
{{#each workoutRoutines}} {{#each workoutRoutines}}
<li class="collection-item clickable" id="{{_id}}">{{routineName}}</li> <li class="collection-item clickable routine" id="{{_id}}">{{routineName}}</li>
{{/each}} {{/each}}
<li class="collection-footer clickable" id="addRoutine"> + Add a Workout Routine</li> <li class="collection-footer clickable" id="addRoutine"> + Add a Workout Routine</li>
</ul> </ul>

View file

@ -45,5 +45,11 @@ Template.workouts.events({
} }
addWorkout(); addWorkout();
} }
} },
'click .routine' (e) {
let routineId = e.currentTarget.id;
console.log("Routine ID set: " + routineId);
Session.set("routineId", routineId);
FlowRouter.go('/workoutLog');
},
}); });

View file

@ -12,12 +12,17 @@ WorkoutLog.allow({
}); });
Meteor.methods({ Meteor.methods({
async 'add.log' (routineId, exerciseName, exerciseType, measure, measureUnits) { async 'add.exerciseToLog' (routineId, exerciseName, exerciseType, exerciseMeasure, exerciseUnitMeasure, exerciseMeasure2, exerciseUnitMeasure2, exerciseMeasure3, exerciseUnitMeasure3, exerciseInstruction) {
check(routineId, String); check(routineId, String);
check(exerciseName, String); check(exerciseName, String);
check(exerciseType, String); check(exerciseType, String);
check(measure, String); check(exerciseMeasure, String);
check(measureUnits, String); check(exerciseUnitMeasure, String);
check(exerciseMeasure2, String);
check(exerciseUnitMeasure2, String);
check(exerciseMeasure3, String);
check(exerciseUnitMeasure3, String);
check(exerciseInstruction, String);
if (!this.userId) { if (!this.userId) {
throw new Meteor.Error('You are not allowed to add routines. Make sure you are logged in with valid user credentials.'); throw new Meteor.Error('You are not allowed to add routines. Make sure you are logged in with valid user credentials.');
@ -27,8 +32,13 @@ Meteor.methods({
routineId: routineId, routineId: routineId,
exerciseName: exerciseName, exerciseName: exerciseName,
exerciseType: exerciseType, exerciseType: exerciseType,
measure: measure, exerciseMeasure: exerciseMeasure,
measureUnits: measureUnits, exerciseUnitMeasure: exerciseUnitMeasure,
exerciseMeasure2: exerciseMeasure2,
exerciseUnitMeasure2: exerciseUnitMeasure2,
exerciseMeasure3: exerciseMeasure3,
exerciseUnitMeasure3: exerciseUnitMeasure3,
exerciseInstruction: exerciseInstruction,
addedBy: this.userId, addedBy: this.userId,
addedOn: new Date(), addedOn: new Date(),
exerciseActive: true, exerciseActive: true,

View file

@ -68,4 +68,11 @@ FlowRouter.route('/measurements', {
action() { action() {
this.render('MainLayout', { main: "measurements"}); this.render('MainLayout', { main: "measurements"});
} }
});
FlowRouter.route('/workoutLog', {
name: 'workoutLog',
action() {
this.render('MainLayout', { main: "workoutLog"});
}
}); });

View file

@ -4,6 +4,7 @@ import { MScripts } from "../imports/api/mScripts";
import { UserInfo } from "../imports/api/userInfo"; import { UserInfo } from "../imports/api/userInfo";
import { Roels } from "meteor/roles"; import { Roels } from "meteor/roles";
import { Workouts } from "../imports/api/workouts"; import { Workouts } from "../imports/api/workouts";
import { WorkoutLog } from "../imports/api/workoutLog";
Meteor.publish("SystemConfig", function() { Meteor.publish("SystemConfig", function() {
try { try {
@ -44,5 +45,14 @@ Meteor.publish("myWorkoutRoutines", function () {
} catch(error) { } catch(error) {
console.log(" ERROR in pulling workout routines: " + error); console.log(" ERROR in pulling workout routines: " + error);
} }
});
Meteor.publish("myWorkoutLog", function () {
try {
if (this.userId) {
return WorkoutLog.find({ "addedBy": this.userId, "exerciseActive": true });
}
} catch(error) {
console.log(" ERROR in pulling workout routines: " + error);
}
}); });