177 lines
7.0 KiB
Python
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)
|