From feebbe613b2eee8bd2bdca5e51e62ebd143e315c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 23 Mar 2019 20:12:01 -0500 Subject: [PATCH] User Profiles Made it where the profiles display the user's info and then then user can edit their info --- app/forms.py | 227 +++++++++++++++++++++++++++++- app/main.py | 29 +++- app/models.py | 1 + app/settings.py | 1 + app/templates/main/profile.jinja2 | 65 +++++++-- 5 files changed, 308 insertions(+), 15 deletions(-) diff --git a/app/forms.py b/app/forms.py index 4f659f5..6a10f15 100644 --- a/app/forms.py +++ b/app/forms.py @@ -5,7 +5,7 @@ from flask_user.forms import unique_email_validator, password_validator from flask_wtf import FlaskForm from wtforms import StringField, HiddenField, PasswordField, BooleanField, SubmitField, validators, ValidationError, \ SelectField -from wtforms.fields.html5 import DateField +from wtforms.fields.html5 import DateField, EmailField import pycountry from app import models @@ -64,6 +64,7 @@ class CustomUserManager(UserManager): def customize(self, app): self.LoginFormClass = CustomLoginForm self.RegisterFormClass = CustomRegisterForm + self.EditUserProfileFormClass = CustomEditUserProfileForm class CustomLoginForm(FlaskForm): @@ -346,3 +347,227 @@ class CustomRegisterForm(FlaskForm): invite_token = HiddenField('Token') submit = SubmitField('Register') + + +class CustomEditUserProfileForm(FlaskForm): + """Edit Profile Form form""" + # MSU Info + net_id = StringField('NetID', validators=[ + validators.DataRequired() + ]) + msu_id = StringField('MSU ID (9-digit WITH dashes)', validators=[ + validators.DataRequired(), + validators.Regexp(r'^\d{3}-\d{3}-\d{3}$', message='Invalid 9-digit MSU ID, be sure to include dashes!') + ]) + department = SelectField('Department', + choices=[('ACC', 'Accounting'), + ('ASE', 'Aerospace Engineering'), + ('AS', 'Aerospace Studies - AFROTC'), + ('AAS', 'African American Studies'), + ('AELC', 'Ag Educ,Leadership & Comm'), + ('ABE', 'Ag. and Bio. Engineering'), + ('AEC', 'Agricultural Economics'), + ('AIS', 'Agricultural Info Sci & Ed'), + ('AGN', 'Agronomy'), + ('ADS', 'Animal Science & Dairy Science'), + ('AN', 'Anthropology'), + ('ALHP', 'Appalachian Ldshp Honors Prog'), + ('AR', 'Archaeology'), + ('ARC', 'Architecture'), + ('ART', 'Art'), + ('BAT', 'BAT Transfer Technical Course'), + ('BCH', 'Biochemistry'), + ('BIO', 'Biological Sciences'), + ('BCS', 'Building Construction Science'), + ('BUS', 'Business Adminstration'), + ('BIS', 'Business Information Systems'), + ('BL', 'Business Law'), + ('BQA', 'Business Quantitive Analysis'), + ('TKB', 'Business Technology'), + ('BTE', 'Business Technology Education'), + ('CHE', 'Chemical Engineering'), + ('CH', 'Chemistry'), + ('FLC', 'Chinese'), + ('CE', 'Civil Engineering'), + ('CFR', 'College of Forest Resources'), + ('CO', 'Communication'), + ('CCL', 'Community College Leadership'), + ('CMB', 'Computational Biology'), + ('CME', 'Computational Engineering'), + ('CPE', 'Computer Engineering'), + ('CSE', 'Computer Science & Engineering'), + ('CP', 'Cooperative Education Program'), + ('COR', 'Corrections'), + ('COE', 'Counselor Education'), + ('CRM', 'Criminology'), + ('CA', 'Culinary Arts'), + ('DSS', 'Disability Support Services'), + ('EC', 'Economics'), + ('EDC', 'Education Core Curriculum'), + ('EDTB', 'Education Student Block'), + ('EDST', 'Education Student Teaching'), + ('EDF', 'Educational Foundations'), + ('EDA', 'Educational Leadership (EDA)'), + ('EDL', 'Educational Leadership (EDL)'), + ('EPY', 'Educational Psychology'), + ('ECE', 'Electrical & Computer Engineer'), + ('EE', 'Electrical Engineering'), + ('EDE', 'Elementary Education'), + ('ENE', 'Engineering Education'), + ('EG', 'Engineering Graphics'), + ('EM', 'Engineering Mechanics'), + ('EN', 'English'), + ('ESL', 'English as Second Language'), + ('EAP', 'English for Academic Purposes'), + ('EPP', 'Entomology & Plant Pathology'), + ('ENS', 'Environmental Science'), + ('EP', 'Exercise Physiology'), + ('EXL', 'Experiental Learning'), + ('FDM', 'Fashion Design & Merchandising'), + ('FIN', 'Finance'), + ('FYE', 'First Year Experience'), + ('FNH', 'Food, Nutrition & Health Promo'), + ('FL', 'Foreign Languages'), + ('FP', 'Forest Products'), + ('FO', 'Forestry'), + ('FLF', 'French'), + ('GLA', 'Gen Liberal Arts'), + ('GS', 'Gender Studies'), + ('GA', 'General Agriculture'), + ('GB', 'General Business'), + ('GE', 'General Engineering'), + ('GNS', 'Genetics'), + ('GR', 'Geography'), + ('GG', 'Geology'), + ('FLG', 'German'), + ('GRD', 'Graduate Studies'), + ('FLH', 'Greek'), + ('HCA', 'Healthcare Administration'), + ('HED', 'Higher Education'), + ('HI', 'History'), + ('HON', 'Honors College'), + ('HDFS', 'Human Development & Family Sci'), + ('HS', 'Human Sciences'), + ('IE', 'Industrial Engineering'), + ('TKI', 'Industrial Technology'), + ('INDT', 'Industrial Technology'), + ('INS', 'Insurance & Risk Management'), + ('IDS', 'Interdisciplinary Studies'), + ('ID', 'Interior Design'), + ('IB', 'International Business'), + ('ISE', 'International Student Exchange'), + ('FLI', 'Italian'), + ('FLJ', 'Japanese'), + ('KI', 'Kinesiology'), + ('LA', 'Landscape Architecture'), + ('FLL', 'Latin'), + ('LSK', 'Learning Skills'), + ('LIB', 'Library'), + ('MGT', 'Management'), + ('DTM', 'Manufacturing'), + ('MKT', 'Marketing'), + ('MA', 'Mathematics'), + ('ME', 'Mechanical Engineering'), + ('MIC', 'Microbiology'), + ('MEC', 'Middle Eastern Culture'), + ('MS', 'Military Science - Army ROTC'), + ('MU', 'Music'), + ('MUE', 'Music Education'), + ('MUA', 'Music, Applied'), + ('NSE', 'National Student Exchange'), + ('NREC', 'Natural Resource & Envir Cons'), + ('PTE', 'Petroleum Engineering'), + ('PHI', 'Philosophy'), + ('PE', 'Physical Education'), + ('PAS', 'Physician Assistant Studies'), + ('PH', 'Physics'), + ('PHY', 'Physiology'), + ('PSS', 'Plant and Soil Sciences'), + ('PS', 'Political Science'), + ('PO', 'Poultry Science'), + ('PSY', 'Psychology'), + ('PPA', 'Public Policy & Administration'), + ('RDG', 'Readings in Education'), + ('REF', 'Real Estate Finance'), + ('REL', 'Religion'), + ('FLR', 'Russian'), + ('EDS', 'Secondary Education'), + ('SL', 'Service Learning'), + ('SW', 'Social Work'), + ('SO', 'Sociology'), + ('FLS', 'Spanish'), + ('EDX', 'Special Education'), + ('SS', 'Sport Studies'), + ('ST', 'Statistics'), + ('SLCE', 'Student Ldshp Comm Engagement'), + ('SBP', 'Sustainable Bioproducts'), + ('TECH', 'Technology'), + ('DTF', 'Technology Foundations'), + ('TKT', 'Technology Teacher Education'), + ('TR', 'Transportation'), + ('UHP', 'University Honors Program'), + ('VTP', 'Veterans Transition Program'), + ('CVM', 'Veterinary Medicine'), + ('VS', 'Veterinary Science'), + ('WFA', 'Wildlife,Fisheries, & Aquaculture'), + ('WS', "Women's Studies") + ], + validators=[ + validators.DataRequired(), + ]) + + # Personal Info + first_name = StringField('First name', validators=[ + validators.DataRequired() + ]) + middle_name = StringField('Middle name', validators=[ + validators.DataRequired() + ]) + last_name = StringField('Last name', validators=[ + validators.DataRequired() + ]) + birth_date = DateField('Birth date', format='%Y-%m-%d', validators=[ + validators.DataRequired() + ]) + pref_name = StringField('Prefered name (If different from first name)', validators=[ + validators.Optional() + ]) + maiden_name = StringField('Maiden name (If Applicable)', validators=[ + validators.Optional() + ]) + + # Contact Info + + sec_email = StringField('Personal E-Mail (optional)', validators=[ + validators.Optional(), + validators.Email('Invalid email address'), + ]) + prim_phone = StringField('Primary phone', validators=[ + validators.DataRequired(), + validate_phone + ]) + sec_phone = StringField('Secondary phone (optional)', validators=[ + validators.Optional(), + validate_phone + ]) + country = CountrySelectField('Country', validators=[ + validators.DataRequired(), + ]) + administrative_area = StringField('State / Province / Region', validators=[ + validators.DataRequired(), + validate_subdivision + ]) + locality = StringField('City / Town', validators=[ + validators.DataRequired(), + ]) + postal_code = StringField('Postal code / ZIP Code', validators=[ + validators.DataRequired(), + ]) + thoroughfare = StringField('Street address', validators=[ + validators.DataRequired(), + ]) + premise = StringField('Apartment, Suite, Box number, etc.', validators=[ + validators.Optional(), + ]) + + submit = SubmitField('Update') diff --git a/app/main.py b/app/main.py index d33efe7..2ef8372 100644 --- a/app/main.py +++ b/app/main.py @@ -1,4 +1,6 @@ -from flask import render_template, Blueprint, url_for, redirect +from flask import render_template, Blueprint, url_for, redirect, session +from flask_user import current_user +import pycountry main_blueprint = Blueprint('main', __name__) @@ -25,7 +27,30 @@ def dashboard(): @main_blueprint.route('/profile') def profile(): """Profile Page""" - return render_template('main/profile.jinja2') + + if current_user.pref_name == "": + full_name=current_user.first_name + ' ' + current_user.middle_name + ' ' + current_user.last_name + else: + full_name = current_user.first_name + ' "' + current_user.pref_name + '" ' + current_user.middle_name + ' ' + current_user.last_name + + info = dict(name=full_name, + department=current_user.department, + email=current_user.email, + net_id=current_user.net_id, + msu_id=current_user.msu_id, + birth_date=current_user.birth_date.strftime('%B %d, %Y'), # Makes human redableS + maiden_name=current_user.maiden_name, + sec_email=current_user.sec_email, + prim_phone=current_user.prim_phone, + sec_phone=current_user.sec_phone, + country=pycountry.countries.get(alpha_2=current_user.country).name, + administrative_area=current_user.administrative_area, + locality=current_user.locality, + postal_code=current_user.postal_code, + thoroughfare=current_user.thoroughfare, + premise=current_user.premise) + print(info) + return render_template('main/profile.jinja2', data=info) @main_blueprint.route('/user/signed-out') diff --git a/app/models.py b/app/models.py index 846af25..f174725 100644 --- a/app/models.py +++ b/app/models.py @@ -28,6 +28,7 @@ class User(db.Model, UserMixin): net_id = db.Column(db.Unicode(8), unique=True) department = db.Column(db.Unicode(50), server_default=u'') + sec_email = db.Column(db.Unicode(255), server_default=u'') prim_phone = db.Column(db.Unicode(50), nullable=False, server_default=u'') sec_phone = db.Column(db.Unicode(50), server_default=u'') diff --git a/app/settings.py b/app/settings.py index 6f410df..cb90308 100644 --- a/app/settings.py +++ b/app/settings.py @@ -26,3 +26,4 @@ USER_PASSLIB_CRYPTCONTEXT_SCHEMES = ['argon2'] # argon2 for hashing USER_AFTER_LOGIN_ENDPOINT = "main.index" USER_AFTER_LOGOUT_ENDPOINT = "main.signed_out" +USER_AFTER_EDIT_USER_PROFILE_ENDPOINT = 'main.profile' diff --git a/app/templates/main/profile.jinja2 b/app/templates/main/profile.jinja2 index 6640302..3e34ff8 100644 --- a/app/templates/main/profile.jinja2 +++ b/app/templates/main/profile.jinja2 @@ -8,33 +8,74 @@ {# Profile Card #}
-
- -
{# user name / classification #}
- Bully Bulldog + {{ data.name }}
- Student + {{ data.department }}

- {# TODO: dynamic data #} {# user data #}

- Email:
- bb123@msstate.edu +

MSU Info
+ E-Mail:
+ {{ data.email }}

- Phone:
- 662-325-5555 -

+ + Net ID:
+ {{ data.net_id }} +

+ + MSU ID:
+ {{ data.msu_id }} +

+ +
+ +
Personal Info
+ + {% if data.maiden_name %} + Maiden Name:
+ {{ data.maiden_name }} +

+ {% endif %} + + Birth Date:
+ {{ data.birth_date }} +

+ + {% if data.sec_email %} + Personal E-Mail:
+ {{ data.sec_email }} +

+ {% endif %} + + Primary Phone:
+ {{ data.prim_phone }} +

+ + {% if data.sec_phone %} + Secondary Phone:
+ {{ data.sec_phone }} +

+ {% endif %} + +
+ +
Address
+ {{ data.thoroughfare }}
+ {{ data.locality }}, {{ data.administrative_area }} {{ data.postal_code }}
+ {{ data.country }} +

+


{# edit profile button #}