From fcc687b97d0acb878d2167a2ef47939b8bc47598 Mon Sep 17 00:00:00 2001
From: stilbruch
Date: Sat, 23 Apr 2022 12:38:19 -0500
Subject: Add select page (it sucks)
---
app/routes.py | 5 +++++
app/templates/workout/record.html | 28 ++--------------------------
app/templates/workout/select.html | 23 +++++++++++++++++++++++
3 files changed, 30 insertions(+), 26 deletions(-)
create mode 100644 app/templates/workout/select.html
(limited to 'app')
diff --git a/app/routes.py b/app/routes.py
index 7ee3986..8f5d8c1 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -116,3 +116,8 @@ def editWorkout():
@login_required
def recordWorkout():
return render_template('workout/record.html')
+
+@app.route("/workout/select", methods=['GET'])
+@login_required
+def selectWorkout():
+ return render_template('workout/select.html')
diff --git a/app/templates/workout/record.html b/app/templates/workout/record.html
index 1a544fc..bc6b695 100644
--- a/app/templates/workout/record.html
+++ b/app/templates/workout/record.html
@@ -5,32 +5,8 @@
diff --git a/app/templates/workout/select.html b/app/templates/workout/select.html
new file mode 100644
index 0000000..c01a4f8
--- /dev/null
+++ b/app/templates/workout/select.html
@@ -0,0 +1,23 @@
+{% extends 'base/layout.html' %}
+
+{% block content %}
+
+
+ {% for workout in current_user.workouts %}
+
+ {% endfor %}
+
+
+
+{% endblock %}
--
cgit v1.2.3
From 5d08424481a8a6ae1b69c96a6ee43394d9aa8963 Mon Sep 17 00:00:00 2001
From: stilbruch
Date: Sat, 23 Apr 2022 13:24:57 -0500
Subject: Start workout record page
---
app/routes.py | 11 +++++++++-
app/templates/workout/record.html | 45 +++++++++++++++++++++++++++++++++++----
2 files changed, 51 insertions(+), 5 deletions(-)
(limited to 'app')
diff --git a/app/routes.py b/app/routes.py
index 8f5d8c1..76ea96a 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -115,7 +115,16 @@ def editWorkout():
@app.route("/workout/record", methods=['GET'])
@login_required
def recordWorkout():
- return render_template('workout/record.html')
+ # Id is required
+ if 'id' not in request.args:
+ return redirect(url_for('home'))
+
+ # Matching workout required
+ workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first()
+ if not workout:
+ return redirect(url_for('home'));
+
+ return render_template('workout/record.html', workout=workout)
@app.route("/workout/select", methods=['GET'])
@login_required
diff --git a/app/templates/workout/record.html b/app/templates/workout/record.html
index bc6b695..6463fe4 100644
--- a/app/templates/workout/record.html
+++ b/app/templates/workout/record.html
@@ -1,12 +1,49 @@
{% extends 'base/layout.html' %}
{% block content %}
-
-
+
-
-
+
Record {{ workout.name }}
+
+ {% for exercise in workout.exercises %}
+
{{ exercise.name }}
+
+
+
+
+
+
+ {% endfor %}
+
+
--
cgit v1.2.3
From 404bba9d518271533d5e4c83dabd8541726bf248 Mon Sep 17 00:00:00 2001
From: stilbruch
Date: Sat, 23 Apr 2022 14:15:35 -0500
Subject: Move routes into seperate folder
---
app/routes.py | 132 --------------------------------------
app/routes/__init__.py | 3 +
app/routes/basic.py | 11 ++++
app/routes/user.py | 52 +++++++++++++++
app/routes/workout.py | 77 ++++++++++++++++++++++
app/static/js/record.js | 9 +++
app/templates/workout/record.html | 9 +--
7 files changed, 157 insertions(+), 136 deletions(-)
delete mode 100644 app/routes.py
create mode 100644 app/routes/__init__.py
create mode 100644 app/routes/basic.py
create mode 100644 app/routes/user.py
create mode 100644 app/routes/workout.py
create mode 100644 app/static/js/record.js
(limited to 'app')
diff --git a/app/routes.py b/app/routes.py
deleted file mode 100644
index 76ea96a..0000000
--- a/app/routes.py
+++ /dev/null
@@ -1,132 +0,0 @@
-from app import app, db
-from flask import render_template, redirect, request, url_for, flash
-from flask_login import current_user, login_user, login_required, logout_user
-from forms import LoginForm, RegisterForm, WorkoutCreateForm
-from tables import User, Workout
-
-@app.route("/", methods=["GET"])
-def index():
- return render_template('index.html')
-
-@app.route("/home", methods=["GET"])
-@login_required
-def home():
- return render_template('home.html')
-
-@app.route("/login", methods=['GET', 'POST'])
-def login():
- form = LoginForm()
- username = form.username.data
- password = form.password.data
-
- if form.validate_on_submit():
- # Valid submission
- user = User.query.filter_by(username=username).first()
-
- # TODO: show user if login succeeded
- if user and user.verify_password(password):
- login_user(user)
- return redirect(url_for('home'))
- else:
- flash("Invalid username or password", "danger")
-
- return render_template('user/login.html', form=form)
-
-@app.route("/logout", methods=['GET', 'POST'])
-def logout():
- logout_user()
- return redirect('/')
-
-@app.route("/register", methods=['GET', 'POST'])
-def register():
- form = RegisterForm()
- # Load data from form
- username = form.username.data
- password = form.password.data
- email = form.email.data
-
- if form.validate_on_submit():
- # Valid submission
- user = User.query.filter_by(username=username).first()
- if not user:
- # No user with this username
- user = User(username, password, email)
- db.session.add(user)
- db.session.commit()
- return redirect(url_for('login'))
- else:
- flash("User already exists", "danger")
-
- return render_template('user/register.html', form=form)
-
-@app.route("/workout/create", methods=['GET', 'POST'])
-@login_required
-def createWorkout():
- form = WorkoutCreateForm()
- name = form.name.data
-
- if form.validate_on_submit():
- # Make sure the user doesn't already have a workout with this name
- workout = Workout.query.filter_by(user_id=current_user.id, name=name).first()
- if not workout:
- # TODO: add exercises
- workout = Workout(current_user, name, [e.data for e in form.exercises.entries])
- db.session.add(workout)
- db.session.commit()
-
- return redirect(url_for('home'));
- else:
- flash("Workout with this name already exists", "danger")
-
- return render_template('workout/create.html', form=form, title="Create a Workout")
-
-@app.route("/workout/edit", methods=['GET', 'POST'])
-@login_required
-def editWorkout():
- # Id is required
- if 'id' not in request.args:
- return redirect(url_for('home'))
-
- # Validate Id
- workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first()
- if not workout:
- return redirect(url_for('home'))
-
- form = WorkoutCreateForm()
-
- if form.validate_on_submit():
- # Form has been submitted, write changes
-
- workout.name = form.name.data
- # TODO: Add exercise changes
-
- # Write changes to database
- db.session.commit()
- return redirect(url_for('home'));
- else:
- form.name.data = workout.name
- form.exercises.pop_entry() # TODO: better way to do this?
-
- for exercise in workout.exercises:
- form.exercises.append_entry(exercise)
-
- return render_template('workout/create.html', form=form, title=f'Edit Workout "{workout.name}"')
-
-@app.route("/workout/record", methods=['GET'])
-@login_required
-def recordWorkout():
- # Id is required
- if 'id' not in request.args:
- return redirect(url_for('home'))
-
- # Matching workout required
- workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first()
- if not workout:
- return redirect(url_for('home'));
-
- return render_template('workout/record.html', workout=workout)
-
-@app.route("/workout/select", methods=['GET'])
-@login_required
-def selectWorkout():
- return render_template('workout/select.html')
diff --git a/app/routes/__init__.py b/app/routes/__init__.py
new file mode 100644
index 0000000..e243576
--- /dev/null
+++ b/app/routes/__init__.py
@@ -0,0 +1,3 @@
+from routes.user import *
+from routes.workout import *
+from routes.basic import *
diff --git a/app/routes/basic.py b/app/routes/basic.py
new file mode 100644
index 0000000..36f42f5
--- /dev/null
+++ b/app/routes/basic.py
@@ -0,0 +1,11 @@
+from app import app, db
+from flask_login import login_required
+
+@app.route("/", methods=["GET"])
+def index():
+ return render_template('index.html')
+
+@app.route("/home", methods=["GET"])
+@login_required
+def home():
+ return render_template('home.html')
diff --git a/app/routes/user.py b/app/routes/user.py
new file mode 100644
index 0000000..4568d97
--- /dev/null
+++ b/app/routes/user.py
@@ -0,0 +1,52 @@
+from app import app, db
+from flask import render_template, redirect, request, url_for, flash
+from flask_login import current_user, login_user, login_required, logout_user
+from forms import LoginForm, RegisterForm
+from tables import User
+
+@app.route("/login", methods=['GET', 'POST'])
+def login():
+ form = LoginForm()
+ username = form.username.data
+ password = form.password.data
+
+ if form.validate_on_submit():
+ # Valid submission
+ user = User.query.filter_by(username=username).first()
+
+ # TODO: show user if login succeeded
+ if user and user.verify_password(password):
+ login_user(user)
+ return redirect(url_for('home'))
+ else:
+ flash("Invalid username or password", "danger")
+
+ return render_template('user/login.html', form=form)
+
+@app.route("/logout", methods=['GET', 'POST'])
+def logout():
+ logout_user()
+ return redirect('/')
+
+@app.route("/register", methods=['GET', 'POST'])
+def register():
+ form = RegisterForm()
+ # Load data from form
+ username = form.username.data
+ password = form.password.data
+ email = form.email.data
+
+ if form.validate_on_submit():
+ # Valid submission
+ user = User.query.filter_by(username=username).first()
+ if not user:
+ # No user with this username
+ user = User(username, password, email)
+ db.session.add(user)
+ db.session.commit()
+ return redirect(url_for('login'))
+ else:
+ flash("User already exists", "danger")
+
+ return render_template('user/register.html', form=form)
+
diff --git a/app/routes/workout.py b/app/routes/workout.py
new file mode 100644
index 0000000..db8ab48
--- /dev/null
+++ b/app/routes/workout.py
@@ -0,0 +1,77 @@
+from app import app, db
+from flask import render_template, redirect, request, url_for, flash
+from flask_login import current_user, login_required
+from forms import LoginForm, RegisterForm, WorkoutCreateForm
+from tables import User, Workout
+
+@app.route("/workout/create", methods=['GET', 'POST'])
+@login_required
+def createWorkout():
+ form = WorkoutCreateForm()
+ name = form.name.data
+
+ if form.validate_on_submit():
+ # Make sure the user doesn't already have a workout with this name
+ workout = Workout.query.filter_by(user_id=current_user.id, name=name).first()
+ if not workout:
+ # TODO: add exercises
+ workout = Workout(current_user, name, [e.data for e in form.exercises.entries])
+ db.session.add(workout)
+ db.session.commit()
+
+ return redirect(url_for('home'));
+ else:
+ flash("Workout with this name already exists", "danger")
+
+ return render_template('workout/create.html', form=form, title="Create a Workout")
+
+@app.route("/workout/edit", methods=['GET', 'POST'])
+@login_required
+def editWorkout():
+ # Id is required
+ if 'id' not in request.args:
+ return redirect(url_for('home'))
+
+ # Validate Id
+ workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first()
+ if not workout:
+ return redirect(url_for('home'))
+
+ form = WorkoutCreateForm()
+
+ if form.validate_on_submit():
+ # Form has been submitted, write changes
+
+ workout.name = form.name.data
+ # TODO: Add exercise changes
+
+ # Write changes to database
+ db.session.commit()
+ return redirect(url_for('home'));
+ else:
+ form.name.data = workout.name
+ form.exercises.pop_entry() # TODO: better way to do this?
+
+ for exercise in workout.exercises:
+ form.exercises.append_entry(exercise)
+
+ return render_template('workout/create.html', form=form, title=f'Edit Workout "{workout.name}"')
+
+@app.route("/workout/record", methods=['GET'])
+@login_required
+def recordWorkout():
+ # Id is required
+ if 'id' not in request.args:
+ return redirect(url_for('home'))
+
+ # Matching workout required
+ workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first()
+ if not workout:
+ return redirect(url_for('home'));
+
+ return render_template('workout/record.html', workout=workout)
+
+@app.route("/workout/select", methods=['GET'])
+@login_required
+def selectWorkout():
+ return render_template('workout/select.html')
diff --git a/app/static/js/record.js b/app/static/js/record.js
new file mode 100644
index 0000000..fedbdd7
--- /dev/null
+++ b/app/static/js/record.js
@@ -0,0 +1,9 @@
+
+// Called when the check at the end of a set line is clicked
+function onClickSetCheck(elem) {
+ if (elem.classList.contains('is-success')) {
+ elem.classList.remove('is-success');
+ } else {
+ elem.classList.add('is-success');
+ }
+}
diff --git a/app/templates/workout/record.html b/app/templates/workout/record.html
index 6463fe4..0908ef8 100644
--- a/app/templates/workout/record.html
+++ b/app/templates/workout/record.html
@@ -22,13 +22,12 @@
-
-
-
+
+
+
@@ -47,4 +46,6 @@
+
+
{% endblock %}
--
cgit v1.2.3
From 316edff9e6b90ab310978c10adbeffa87d18e746 Mon Sep 17 00:00:00 2001
From: stilbruch
Date: Sat, 23 Apr 2022 14:26:59 -0500
Subject: Fix workout deleting option
---
app/routes/__init__.py | 1 +
app/routes/api.py | 17 +++++++++++++++++
app/routes/basic.py | 1 +
app/routes/user.py | 1 +
app/templates/home.html | 2 +-
5 files changed, 21 insertions(+), 1 deletion(-)
create mode 100644 app/routes/api.py
(limited to 'app')
diff --git a/app/routes/__init__.py b/app/routes/__init__.py
index e243576..09fcbf3 100644
--- a/app/routes/__init__.py
+++ b/app/routes/__init__.py
@@ -1,3 +1,4 @@
+from routes.api import *
from routes.user import *
from routes.workout import *
from routes.basic import *
diff --git a/app/routes/api.py b/app/routes/api.py
new file mode 100644
index 0000000..58b4732
--- /dev/null
+++ b/app/routes/api.py
@@ -0,0 +1,17 @@
+from app import app, db
+from flask import redirect, request
+from flask_login import current_user, login_required
+from tables import Workout
+
+@app.route("/api/workout/delete", methods=['GET'])
+@login_required
+def api_workout_delete():
+ if 'id' not in request.args:
+ return redirect('/home');
+
+ workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first()
+ if workout:
+ db.session.delete(workout)
+ db.session.commit()
+
+ return redirect('/home')
diff --git a/app/routes/basic.py b/app/routes/basic.py
index 36f42f5..5883b97 100644
--- a/app/routes/basic.py
+++ b/app/routes/basic.py
@@ -1,4 +1,5 @@
from app import app, db
+from flask import render_template
from flask_login import login_required
@app.route("/", methods=["GET"])
diff --git a/app/routes/user.py b/app/routes/user.py
index 4568d97..d218738 100644
--- a/app/routes/user.py
+++ b/app/routes/user.py
@@ -24,6 +24,7 @@ def login():
return render_template('user/login.html', form=form)
@app.route("/logout", methods=['GET', 'POST'])
+@login_required
def logout():
logout_user()
return redirect('/')
diff --git a/app/templates/home.html b/app/templates/home.html
index 9f8dfe9..c9aa90d 100644
--- a/app/templates/home.html
+++ b/app/templates/home.html
@@ -79,7 +79,7 @@
--
cgit v1.2.3
From 3d0202b4faaef7ff0900bcfefca4c88907a2b6d4 Mon Sep 17 00:00:00 2001
From: stilbruch
Date: Sat, 23 Apr 2022 15:08:27 -0500
Subject: Update record workout page
---
app/static/js/record.js | 33 ++++++++++++++++++++
app/templates/base/layout.html | 2 +-
app/templates/workout/record.html | 64 ++++++++++++++++++++-------------------
3 files changed, 67 insertions(+), 32 deletions(-)
(limited to 'app')
diff --git a/app/static/js/record.js b/app/static/js/record.js
index fedbdd7..75aa148 100644
--- a/app/static/js/record.js
+++ b/app/static/js/record.js
@@ -1,9 +1,42 @@
+// Register 'Enter' listeners on all inputs
+Array.from(document.getElementsByClassName('input'))
+ .filter(e => e.type == 'number')
+ .forEach(e => e.addEventListener('keyup', function(event) {
+ if (event.key == 'Enter') {
+ console.log("ENTER");
+ }
+ }))
+
+function checkSet(row) {
+ // Disable input editing
+ row.children[1].firstChild.disabled = true;
+ row.children[2].firstChild.disabled = true;
+
+ // Add is-success to inputs
+ row.children[1].firstChild.classList.add('is-success')
+ row.children[2].firstChild.classList.add('is-success')
+}
+
+function uncheckSet(row) {
+ // Re-enable input editing
+ row.children[1].firstChild.disabled = false;
+ row.children[2].firstChild.disabled = false;
+
+ // Remove is-success from inputs
+ row.children[1].firstChild.classList.remove('is-success')
+ row.children[2].firstChild.classList.remove('is-success')
+}
+
// Called when the check at the end of a set line is clicked
function onClickSetCheck(elem) {
if (elem.classList.contains('is-success')) {
elem.classList.remove('is-success');
+
+ uncheckSet(elem.parentElement.parentElement);
} else {
elem.classList.add('is-success');
+
+ checkSet(elem.parentElement.parentElement);
}
}
diff --git a/app/templates/base/layout.html b/app/templates/base/layout.html
index 89ad385..fe83440 100644
--- a/app/templates/base/layout.html
+++ b/app/templates/base/layout.html
@@ -47,7 +47,7 @@
-
+
diff --git a/app/templates/workout/record.html b/app/templates/workout/record.html
index 0908ef8..3dfb2c8 100644
--- a/app/templates/workout/record.html
+++ b/app/templates/workout/record.html
@@ -7,39 +7,41 @@
Record {{ workout.name }}
{% for exercise in workout.exercises %}
-
{{ exercise.name }}
-
-
+
{{ exercise.name }}
+
-
-
+
+
+
{% endfor %}
--
cgit v1.2.3
From 4f1e55112138a1f3b4be3bf23e3740ae3effac35 Mon Sep 17 00:00:00 2001
From: stilbruch
Date: Sat, 23 Apr 2022 15:48:45 -0500
Subject: Add javascript to add sets while recording workout
---
app/routes/workout.py | 2 +-
app/static/js/record.js | 64 ++++++++++++++++++++++--------
app/templates/base/form.html | 2 +-
app/templates/workout/record.html | 83 ++++++++++++++++++---------------------
4 files changed, 89 insertions(+), 62 deletions(-)
(limited to 'app')
diff --git a/app/routes/workout.py b/app/routes/workout.py
index db8ab48..8615156 100644
--- a/app/routes/workout.py
+++ b/app/routes/workout.py
@@ -69,7 +69,7 @@ def recordWorkout():
if not workout:
return redirect(url_for('home'));
- return render_template('workout/record.html', workout=workout)
+ return render_template('workout/record.html', workout=workout, form=None)
@app.route("/workout/select", methods=['GET'])
@login_required
diff --git a/app/static/js/record.js b/app/static/js/record.js
index 75aa148..aba6785 100644
--- a/app/static/js/record.js
+++ b/app/static/js/record.js
@@ -4,11 +4,44 @@ Array.from(document.getElementsByClassName('input'))
.filter(e => e.type == 'number')
.forEach(e => e.addEventListener('keyup', function(event) {
if (event.key == 'Enter') {
- console.log("ENTER");
+ // TODO implement
+ console.log("ENTER")
}
}))
-function checkSet(row) {
+function setReset(row, values=true) {
+ let lbsInput = row.children[1].children[0];
+ let repsInput = row.children[2].children[0];
+ let doneButton = row.children[3].children[0];
+
+ // Enable inputs
+ lbsInput.disabled = false;
+ repsInput.disabled = false;
+
+ // Remove classes
+ lbsInput.classList.remove('is-success');
+ lbsInput.classList.remove('is-danger');
+ repsInput.classList.remove('is-success');
+ repsInput.classList.remove('is-danger');
+
+ doneButton.classList.remove('is-success');
+
+ if (values) {
+ lbsInput.value = '';
+ repsInput.value = '';
+ }
+}
+
+function setSetid(row, id) {
+ let setNumber = row.children[0];
+ let lbsInput = row.children[1].children[0];
+ let repsInput = row.children[2].children[0];
+ let doneButton = row.children[3].children[0];
+
+ setNumber.textContent = id + 1;
+}
+
+function setCheck(row) {
// Disable input editing
row.children[1].firstChild.disabled = true;
row.children[2].firstChild.disabled = true;
@@ -18,25 +51,24 @@ function checkSet(row) {
row.children[2].firstChild.classList.add('is-success')
}
-function uncheckSet(row) {
- // Re-enable input editing
- row.children[1].firstChild.disabled = false;
- row.children[2].firstChild.disabled = false;
-
- // Remove is-success from inputs
- row.children[1].firstChild.classList.remove('is-success')
- row.children[2].firstChild.classList.remove('is-success')
-}
-
// Called when the check at the end of a set line is clicked
function onClickSetCheck(elem) {
if (elem.classList.contains('is-success')) {
- elem.classList.remove('is-success');
-
- uncheckSet(elem.parentElement.parentElement);
+ setReset(elem.parentElement.parentElement, false);
} else {
elem.classList.add('is-success');
- checkSet(elem.parentElement.parentElement);
+ setCheck(elem.parentElement.parentElement);
}
}
+
+function onClickAddSet(elem) {
+ // Create the new row
+ let tableBody = elem.parentElement.parentElement.children[1].children[1];
+ let row = tableBody.children[0].cloneNode(true);
+
+ // Add new row to table
+ setReset(row);
+ setSetid(row, tableBody.children.length)
+ tableBody.appendChild(row)
+}
diff --git a/app/templates/base/form.html b/app/templates/base/form.html
index 72083ae..9f356e0 100644
--- a/app/templates/base/form.html
+++ b/app/templates/base/form.html
@@ -4,7 +4,7 @@
-
{{ title }}
+
{% block title %}{% endblock %}
{% with messages = get_flashed_messages(with_categories=true) %}
diff --git a/app/templates/workout/record.html b/app/templates/workout/record.html
index 3dfb2c8..94fe611 100644
--- a/app/templates/workout/record.html
+++ b/app/templates/workout/record.html
@@ -1,52 +1,47 @@
-{% extends 'base/layout.html' %}
+{% extends 'base/form.html' %}
-{% block content %}
-
-
-
-
Record {{ workout.name }}
-
- {% for exercise in workout.exercises %}
-
{{ exercise.name }}
-
-