Files
bloodpressure/app/routes.py
2024-12-24 00:57:08 +11:00

177 lines
7.0 KiB
Python

from flask import Blueprint, render_template, redirect, request, url_for, flash
from werkzeug.security import generate_password_hash, check_password_hash
from app.models import Profile, Reading, db, User
from app.forms import DeleteForm, LoginForm, ProfileForm, ReadingForm, SignupForm
from flask_login import login_user, login_required, current_user, logout_user
import base64
main = Blueprint('main', __name__)
auth = Blueprint('auth', __name__)
user = Blueprint('user', __name__)
@auth.route('/signup', methods=['GET', 'POST'])
def signup():
form = SignupForm()
if form.validate_on_submit():
hashed_password = generate_password_hash(form.password.data)
new_user = User(username=form.username.data, password_hash=hashed_password)
db.session.add(new_user)
db.session.commit()
flash("Account created successfully. Please log in.", "success")
return redirect(url_for('auth.login'))
return render_template('signup.html', form=form)
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and check_password_hash(user.password_hash, form.password.data):
login_user(user)
flash("Logged in successfully.", "success")
return redirect(url_for('main.dashboard'))
flash("Invalid username or password.", "danger")
return render_template('login.html', form=form)
@auth.route('/logout')
@login_required
def logout():
logout_user() # Logs out the current user
flash('You have been logged out.', 'success')
return redirect(url_for('auth.login')) # Redirect to login page or home page
@main.route('/')
@login_required
def dashboard():
from datetime import datetime, timedelta
profile = current_user.profile
# Get all readings for the user
readings = Reading.query.filter_by(user_id=current_user.id).order_by(Reading.timestamp.desc()).all()
# Weekly summary (last 7 days)
one_week_ago = datetime.now() - timedelta(days=7)
weekly_readings = [r for r in readings if r.timestamp >= one_week_ago]
systolic_avg = round(sum(r.systolic for r in weekly_readings) / len(weekly_readings), 1) if weekly_readings else 0
diastolic_avg = round(sum(r.diastolic for r in weekly_readings) / len(weekly_readings), 1) if weekly_readings else 0
heart_rate_avg = round(sum(r.heart_rate for r in weekly_readings) / len(weekly_readings), 1) if weekly_readings else 0
# Progress badges
badges = []
if len(readings) >= 10:
badges.append("10 Readings Logged")
if len(readings) >= 100:
badges.append("100 Readings Milestone")
if len(weekly_readings) >= 7:
badges.append("Logged Readings for 7 Days")
# Pass the delete form to the template
delete_form = DeleteForm()
return render_template('dashboard.html', readings=readings, profile=profile, badges=badges,
systolic_avg=systolic_avg, diastolic_avg=diastolic_avg, heart_rate_avg=heart_rate_avg,
delete_form=delete_form)
@main.route('/dashboard/filter', methods=['POST'])
@login_required
def filter_dashboard():
from datetime import datetime
start_date = request.form.get('start_date')
end_date = request.form.get('end_date')
# Parse dates and filter readings
readings = Reading.query.filter(
Reading.user_id == current_user.id,
Reading.timestamp >= datetime.strptime(start_date, '%Y-%m-%d'),
Reading.timestamp <= datetime.strptime(end_date, '%Y-%m-%d')
).order_by(Reading.timestamp.desc()).all()
# Pass the delete form to the template
delete_form = DeleteForm()
return render_template('dashboard.html', readings=readings, delete_form=delete_form)
@main.route('/add-reading', methods=['GET', 'POST'])
@login_required
def add_reading():
form = ReadingForm()
if form.validate_on_submit():
new_reading = Reading(
user_id=current_user.id,
timestamp=form.timestamp.data,
systolic=form.systolic.data,
diastolic=form.diastolic.data,
heart_rate=form.heart_rate.data
)
db.session.add(new_reading)
db.session.commit()
flash("Reading added successfully.", "success")
return redirect(url_for('main.dashboard'))
return render_template('add_reading.html', form=form)
@main.route('/reading/<int:reading_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_reading(reading_id):
reading = Reading.query.get_or_404(reading_id)
# Ensure the reading belongs to the logged-in user
if reading.user_id != current_user.id:
flash('You are not authorized to edit this reading.', 'danger')
return redirect(url_for('main.dashboard'))
form = ReadingForm(obj=reading) # Populate form with existing reading data
if form.validate_on_submit():
reading.timestamp = form.timestamp.data
reading.systolic = form.systolic.data
reading.diastolic = form.diastolic.data
reading.heart_rate = form.heart_rate.data
db.session.commit()
flash('Reading updated successfully!', 'success')
return redirect(url_for('main.dashboard'))
return render_template('edit_reading.html', form=form, reading=reading)
@main.route('/reading/<int:reading_id>/delete', methods=['POST'])
@login_required
def delete_reading(reading_id):
reading = Reading.query.get_or_404(reading_id)
# Ensure the reading belongs to the logged-in user
if reading.user_id != current_user.id:
flash('You are not authorized to delete this reading.', 'danger')
return redirect(url_for('main.dashboard'))
db.session.delete(reading)
db.session.commit()
flash('Reading deleted successfully!', 'success')
return redirect(url_for('main.dashboard'))
@user.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
profile = current_user.profile or Profile(user_id=current_user.id)
form = ProfileForm(obj=profile)
if form.validate_on_submit():
# Update profile fields
profile.name = form.name.data
profile.email = form.email.data
profile.systolic_threshold = form.systolic_threshold.data or profile.systolic_threshold
profile.diastolic_threshold = form.diastolic_threshold.data or profile.diastolic_threshold
profile.dark_mode = form.dark_mode.data
# Handle profile picture upload
if form.profile_pic.data:
file_data = form.profile_pic.data.read()
profile.profile_pic = base64.b64encode(file_data).decode('utf-8')
db.session.add(profile)
db.session.commit()
flash('Profile updated successfully!', 'success')
return redirect(url_for('user.profile'))
return render_template('profile.html', form=form, profile=profile)