Files
bloodpressure/app/forms.py
T

114 lines
4.0 KiB
Python

from typing import Optional
from flask_wtf import FlaskForm
from pytz import all_timezones
from wtforms import BooleanField, FileField, SelectField, StringField, PasswordField, SubmitField, IntegerField, DateTimeLocalField
from wtforms.validators import DataRequired, Length, EqualTo, ValidationError, Email, Optional, NumberRange
from app.models import User
from datetime import datetime
class SignupForm(FlaskForm):
username = StringField(
'Username',
validators=[
DataRequired(),
Length(min=4, max=20, message="Username must be between 4 and 20 characters.")
]
)
password = PasswordField(
'Password',
validators=[
DataRequired(),
Length(min=6, message="Password must be at least 6 characters long.")
]
)
confirm_password = PasswordField(
'Confirm Password',
validators=[
DataRequired(),
EqualTo('password', message="Passwords must match.")
]
)
submit = SubmitField('Sign Up')
# Custom validator to check if username is already taken
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError("Username is already taken. Please choose a different one.")
class LoginForm(FlaskForm):
username = StringField(
'Username',
validators=[DataRequired(message="Username is required.")]
)
password = PasswordField(
'Password',
validators=[DataRequired(message="Password is required.")]
)
submit = SubmitField('Login')
class ReadingForm(FlaskForm):
timestamp = DateTimeLocalField(
'Timestamp',
format='%Y-%m-%dT%H:%M',
default=datetime.now, # Set default to current time
validators=[DataRequired(message="Timestamp is required.")]
)
systolic = IntegerField(
'Systolic (mmHg)',
validators=[
DataRequired(),
NumberRange(min=50, max=250, message="Systolic pressure must be between 50 and 250 mmHg.")
]
)
diastolic = IntegerField(
'Diastolic (mmHg)',
validators=[
DataRequired(),
NumberRange(min=30, max=150, message="Diastolic pressure must be between 30 and 150 mmHg.")
]
)
heart_rate = IntegerField(
'Heart Rate (bpm)',
validators=[
DataRequired(),
NumberRange(min=30, max=200, message="Heart rate must be between 30 and 200 bpm.")
]
)
submit = SubmitField('Save Reading')
def validate_timestamp(self, field):
from flask_login import current_user
from pytz import timezone, AmbiguousTimeError, NonExistentTimeError
if not field.data:
return
if not 1900 <= field.data.year <= 2100:
raise ValidationError('Choose a date between 1900 and 2100.')
profile = current_user.profile
tz = timezone(profile.timezone if profile and profile.timezone else 'UTC')
try:
tz.localize(field.data.replace(tzinfo=None), is_dst=None)
except (AmbiguousTimeError, NonExistentTimeError):
raise ValidationError('This local time is ambiguous or skipped by daylight saving. Choose an unambiguous local time.')
class DeleteForm(FlaskForm):
submit = SubmitField('Delete')
class ProfileForm(FlaskForm):
name = StringField('Name', validators=[Optional()])
email = StringField('Email', validators=[Optional(), Email()])
profile_pic = FileField('Profile Picture (optional)')
timezone = SelectField('Timezone', choices=[(tz, tz) for tz in all_timezones])
systolic_threshold = IntegerField(
'Systolic Threshold (mmHg)',
validators=[Optional(), NumberRange(min=90, max=200)]
)
diastolic_threshold = IntegerField(
'Diastolic Threshold (mmHg)',
validators=[Optional(), NumberRange(min=60, max=120)]
)
dark_mode = BooleanField('Enable Dark Mode')
submit = SubmitField('Save Settings')