User Profiles

Made it where the profiles display the user's info and then then user can edit their info
This commit is contained in:
Aaron Kimbrell
2019-03-23 20:12:01 -05:00
parent 905315aa0b
commit feebbe613b
5 changed files with 308 additions and 15 deletions

View File

@@ -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')

View File

@@ -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')

View File

@@ -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'')

View File

@@ -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'

View File

@@ -8,33 +8,74 @@
{# Profile Card #}
<div class='card mx-auto mt-5 col-lg-6 col-12 shadow-sm'>
<div class='card-body'>
<div class='row justify-content-center mb-3'>
<i class='display-1 mx-auto text-muted fas fa-user-circle'></i>
</div>
{# user name / classification #}
<div class='row justify-content-center'>
<span class='h3'>Bully Bulldog</span>
<span class='h3'>{{ data.name }}</span>
</div>
<div class='row justify-content-center'>
<span class='h5'>Student</span>
<span class='h5'>{{ data.department }}</span>
</div>
<hr/>
{# TODO: dynamic data #}
{# user data #}
<p class='text-lg-left'>
<b>Email:</b><br/>
bb123@msstate.edu
<h5>MSU Info</h5>
<b>E-Mail:</b><br/>
{{ data.email }}
<br/><br/>
<b>Phone:</b><br/>
662-325-5555
</p>
<b>Net ID:</b><br/>
{{ data.net_id }}
<br/><br/>
<b>MSU ID:</b><br/>
{{ data.msu_id }}
<br/><br/>
<hr>
<h5>Personal Info</h5>
{% if data.maiden_name %}
<b>Maiden Name:</b><br/>
{{ data.maiden_name }}
<br/><br/>
{% endif %}
<b>Birth Date:</b><br/>
{{ data.birth_date }}
<br/><br/>
{% if data.sec_email %}
<b>Personal E-Mail:</b><br/>
{{ data.sec_email }}
<br/><br/>
{% endif %}
<b>Primary Phone:</b><br/>
{{ data.prim_phone }}
<br/><br/>
{% if data.sec_phone %}
<b>Secondary Phone:</b><br/>
{{ data.sec_phone }}
<br/><br/>
{% endif %}
<hr>
<h5>Address</h5>
{{ data.thoroughfare }}<br>
{{ data.locality }}, {{ data.administrative_area }} {{ data.postal_code }}<br>
{{ data.country }}
<br/><br/>
</p>
<hr/>
{# edit profile button #}
<div class='col text-center'>
<a href='' class='btn btn-primary px-5'>Edit profile</a>
<a href='{{ url_for('user.edit_user_profile') }}'class='btn btn-primary px-5'>Edit profile</a>
</div>
</div>
</div>