summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/routes.py36
-rw-r--r--app/static/css/style.css4
-rw-r--r--app/tables/workout.py22
-rw-r--r--app/templates/home.html86
-rw-r--r--app/templates/workout/create.html66
-rw-r--r--app/templates/workout/manage.html6
6 files changed, 131 insertions, 89 deletions
diff --git a/app/routes.py b/app/routes.py
index 36fb0ba..1ff1023 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -1,5 +1,5 @@
from app import app, db
-from flask import render_template, redirect, url_for, flash
+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
@@ -70,7 +70,7 @@ def createWorkout():
workout = Workout.query.filter_by(user_id=current_user.id, name=name).first()
if not workout:
# TODO: add exercises
- workout = Workout(current_user, name, None)
+ workout = Workout(current_user, name, [e.data for e in form.exercises.entries])
db.session.add(workout)
db.session.commit()
@@ -79,3 +79,35 @@ def createWorkout():
flash("Workout with this name already exists", "danger")
return render_template('workout/create.html', form=form)
+
+@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)
diff --git a/app/static/css/style.css b/app/static/css/style.css
index 497a2bf..e5eb7a3 100644
--- a/app/static/css/style.css
+++ b/app/static/css/style.css
@@ -10,3 +10,7 @@
-o-background-size: cover;
background-size: cover;
}
+
+.welcome {
+ background: linear-gradient(to right, #5B86E5, #36D1DC);
+}
diff --git a/app/tables/workout.py b/app/tables/workout.py
index 81f9a68..b86a3db 100644
--- a/app/tables/workout.py
+++ b/app/tables/workout.py
@@ -4,20 +4,38 @@ from app import db, login_manager
class Exercise(db.Model):
__tablename__ = 'exercises'
id = db.Column(db.Integer, primary_key=True)
+ name = db.Column(db.String(100), nullable=False)
+ sets = db.Column(db.Integer)
+ reps = db.Column(db.Integer)
+ # Workout Relationship
+ workout_id = db.Column(db.Integer, db.ForeignKey('workouts.id'))
+
+ def __init__(self, name, sets, reps):
+ self.name = name
+ self.sets = sets
+ self.reps = reps
+
+ def __repr__(self):
+ return f'<Exercise {self.name} {self.sets}x{self.reps}>'
# Represents a singular workout
class Workout(db.Model):
__tablename__ = 'workouts'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
-
- # User Relationship
+ # foreign keys
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
+ # relationships
+ exercises = db.relationship("Exercise", backref='workout', lazy='dynamic')
def __init__(self, user, name, exercises):
self.name = name
self.user_id = user.id
+ # Create exercises
+ for exercise in exercises:
+ self.exercises.append(Exercise(exercise['name'], exercise['sets'], exercise['reps']))
+
def __repr__(self):
return f'<Workout {self.name}>'
diff --git a/app/templates/home.html b/app/templates/home.html
index fb47a68..11179cd 100644
--- a/app/templates/home.html
+++ b/app/templates/home.html
@@ -10,7 +10,7 @@
Hello, {{ current_user.username }}.
</h1>
<h2 class="subtitle">
- %subtitle%
+ Welcome Back
</h2>
</div>
</div>
@@ -49,6 +49,38 @@
<div class="card events-card">
<header class="card-header">
<p class="card-header-title">
+ My Workouts
+ </p>
+ </header>
+ <div class="card-table">
+ <div class="content">
+ <table class="table is-fullwidth is-striped">
+ <tbody>
+ {% for workout in current_user.workouts %}
+ <tr>
+ <td>{{ workout.name }}</td>
+ <td>{{ workout.exercises.count() }} exercises</td>
+ <td class="level-right">
+ <p class="buttons">
+ <a class="button is-small is-primary" href="/workout/edit?id={{ workout.id }}">Edit</a>
+ <a class="button is-small is-danger" href="#">Delete</a>
+ </p>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <footer class="card-footer">
+ <a href="/workout/create" class="card-footer-item">Create New</a>
+ </footer>
+ </div>
+ </div>
+ <div class="column is-6">
+ <div class="card events-card">
+ <header class="card-header">
+ <p class="card-header-title">
Recent Workouts
</p>
</header>
@@ -80,58 +112,6 @@
</footer>
</div>
</div>
- <div class="column is-6">
- <div class="card">
- <header class="card-header">
- <p class="card-header-title">
- Inventory Search
- </p>
- <a href="#" class="card-header-icon" aria-label="more options">
- <span class="icon">
- <i class="fa fa-angle-down" aria-hidden="true"></i>
- </span>
- </a>
- </header>
- <div class="card-content">
- <div class="content">
- <div class="control has-icons-left has-icons-right">
- <input class="input is-large" type="text" placeholder="">
- <span class="icon is-medium is-left">
- <i class="fa fa-search"></i>
- </span>
- <span class="icon is-medium is-right">
- <i class="fa fa-check"></i>
- </span>
- </div>
- </div>
- </div>
- </div>
- <div class="card">
- <header class="card-header">
- <p class="card-header-title">
- User Search
- </p>
- <a href="#" class="card-header-icon" aria-label="more options">
- <span class="icon">
- <i class="fa fa-angle-down" aria-hidden="true"></i>
- </span>
- </a>
- </header>
- <div class="card-content">
- <div class="content">
- <div class="control has-icons-left has-icons-right">
- <input class="input is-large" type="text" placeholder="">
- <span class="icon is-medium is-left">
- <i class="fa fa-search"></i>
- </span>
- <span class="icon is-medium is-right">
- <i class="fa fa-check"></i>
- </span>
- </div>
- </div>
- </div>
- </div>
- </div>
</div>
</div>
diff --git a/app/templates/workout/create.html b/app/templates/workout/create.html
index eaf5f39..cdd1191 100644
--- a/app/templates/workout/create.html
+++ b/app/templates/workout/create.html
@@ -7,7 +7,7 @@
<div class="field-body">
<div class="field">
<p class="control is-expanded has-icons-left">
- <input class="input" name="name" type="text" placeholder="Workout Name">
+ <input class="input" name="name" type="text" placeholder="Workout Name", value="{{ form.name.data or "" }}">
<span class="icon is-small is-left">
<i class="fa fa-tag"></i>
</span>
@@ -16,39 +16,41 @@
</div>
</div>
<div id="rows" class="field">
- <div class="field is-horizontal">
- <div class="field-body">
- <div class="field">
- <p class="control is-expanded has-icons-left">
- <input class="input" name='exercises-0-name' type="text" placeholder="Exercise Name">
- <span class="icon is-small is-left">
- <i class="fa fa-tag"></i>
+ {% for entry in form.exercises.entries %}
+ <div class="field is-horizontal">
+ <div class="field-body">
+ <div class="field">
+ <p class="control is-expanded has-icons-left">
+ <input class="input" name='exercises-0-name' type="text" placeholder="Exercise Name", value="{{ entry.data['name'] or "" }}">
+ <span class="icon is-small is-left">
+ <i class="fa fa-tag"></i>
+ </span>
+ </p>
+ </div>
+ <div class="field">
+ <p class="control is-expanded has-icons-left">
+ <input class="input" name='exercises-0-sets' type="number" placeholder="Sets" min="1" max="100" value="{{ entry.data['sets'] or "" }}">
+ <span class="icon is-small is-left">
+ <i class="fa fa-calculator"></i>
+ </span>
+ </p>
+ </div>
+ <div class="field">
+ <p class="control is-expanded has-icons-left">
+ <input class="input" name='exercises-0-reps' type="number" placeholder="Reps" min="1" max="100" value="{{ entry.data['reps'] or "" }}">
+ <span class="icon is-small is-left">
+ <i class="fa fa-calculator"></i>
+ </span>
+ </p>
+ </div>
+ <p class="button is-danger" onclick="handleDel(this)">
+ <span class="icon is-small">
+ <i class="fa fa-minus"></i>
</span>
</p>
</div>
- <div class="field">
- <p class="control is-expanded has-icons-left">
- <input class="input" name='exercises-0-sets' type="number" placeholder="Sets" min="1" max="100">
- <span class="icon is-small is-left">
- <i class="fa fa-calculator"></i>
- </span>
- </p>
- </div>
- <div class="field">
- <p class="control is-expanded has-icons-left">
- <input class="input" name='exercises-0-reps' type="number" placeholder="Reps" min="1" max="100">
- <span class="icon is-small is-left">
- <i class="fa fa-calculator"></i>
- </span>
- </p>
- </div>
- <p class="button is-danger" onclick="handleDel(this)">
- <span class="icon is-small">
- <i class="fa fa-minus"></i>
- </span>
- </p>
</div>
- </div>
+ {% endfor %}
</div>
<div class="field is-grouped is-grouped-right">
<p class="buttons">
@@ -69,12 +71,11 @@
</div>
<script>
- var rowId = 0;
+ var rowId = {{ form.exercises.entries | length }};
function handleAdd() {
rowsDiv = document.getElementById("rows");
newRow = rowsDiv.children[0].cloneNode(true);
- rowId++;
exerciseNameInput = newRow.children[0].children[0].children[0].children[0];
exerciseNameInput.value = '';
@@ -88,6 +89,7 @@
exerciseRepInput.value = '';
exerciseRepInput.name = 'exercises-' + rowId + '-reps';
+ rowId++;
rowsDiv.append(newRow);
}
diff --git a/app/templates/workout/manage.html b/app/templates/workout/manage.html
new file mode 100644
index 0000000..95f03f5
--- /dev/null
+++ b/app/templates/workout/manage.html
@@ -0,0 +1,6 @@
+{% extends 'base/layout.html' %}
+
+{% block content %}
+<div class="container">
+</div>
+{% endblock %}