feat(user); adds update methods and template
This commit is contained in:
@@ -7,6 +7,7 @@ from app.extensions import db
|
||||
from app.utils.alert_type import AlertType
|
||||
from app.utils.errors.users.user_register_errors import UserRegisterErrors
|
||||
from app.utils.flash_message import FlashMessage
|
||||
from app.utils.flash_message_category import FlashMessageCategory
|
||||
from app.utils.validators import UserValidators
|
||||
class UserService:
|
||||
|
||||
@@ -64,4 +65,53 @@ class UserService:
|
||||
except UserRegisterErrors as e:
|
||||
flash(FlashMessage(e.message, AlertType.DANGER.value ))
|
||||
|
||||
@staticmethod
|
||||
def get_user():
|
||||
user_id = session.get("id")
|
||||
if user_id is None:
|
||||
session.clear()
|
||||
return None
|
||||
user = db.session.execute(db.select(User).filter_by(id=user_id)).one_or_none()
|
||||
if user is None:
|
||||
session.clear()
|
||||
return user
|
||||
|
||||
@staticmethod
|
||||
def update_password(form: ImmutableMultiDict, user: User):
|
||||
try:
|
||||
password = UserValidators.is_valid_password(form.get("password"))
|
||||
new_password = UserValidators.is_valid_password(form.get("new_password"))
|
||||
new_password_confirmation = UserValidators.is_valid_password(form.get("new_password_confirmation"))
|
||||
UserValidators.passwords_match(new_password, new_password_confirmation)
|
||||
|
||||
if check_password_hash(user.password, password):
|
||||
user.password = generate_password_hash(new_password)
|
||||
db.session.commit()
|
||||
db.session.flush()
|
||||
flash(FlashMessage("Password updated", AlertType.SUCCESS.value, FlashMessageCategory.PASSWORD))
|
||||
else:
|
||||
raise UserRegisterErrors("Invalid password")
|
||||
except UserRegisterErrors as e:
|
||||
db.session.rollback()
|
||||
flash(FlashMessage(e.message, AlertType.DANGER.value, FlashMessageCategory.PASSWORD ))
|
||||
|
||||
@staticmethod
|
||||
def update_personal_info(form: ImmutableMultiDict, user: User):
|
||||
try:
|
||||
email: str = UserValidators.is_valid_email(form.get("email"))
|
||||
phone_number: str = UserValidators.is_valid_phone_number(form.get("phonenumber"))
|
||||
address: str = UserValidators.is_valid_address(form.get("address"))
|
||||
|
||||
user.email = email
|
||||
user.phone_number = phone_number
|
||||
user.address = address
|
||||
db.session.commit()
|
||||
db.session.flush()
|
||||
|
||||
flash(FlashMessage("Personal information updated", AlertType.SUCCESS.value, FlashMessageCategory.PERSONAL_INFO))
|
||||
except UserRegisterErrors as e:
|
||||
db.session.rollback()
|
||||
flash(FlashMessage(e.message, AlertType.DANGER.value, FlashMessageCategory.PERSONAL_INFO ))
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,177 @@
|
||||
{% extends "layout/layout.html" %}
|
||||
{% block title %} Users {% endblock %}
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<h1>User's page!</h1>
|
||||
{% extends "layout/layout.html" %} {% from "forms/submit-btn.html" import
|
||||
form_submit_button %} {% from "forms/validation-block.html" import
|
||||
form_field_validation %} {% from "layout/inner_header.html" import
|
||||
inner_header%} {% block title %} Users {% endblock %} {% block head %} {{
|
||||
super() }}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ url_for('static', filename='css/user.css') }}"
|
||||
/>
|
||||
{% endblock %} {% block content %}
|
||||
<div class="container h-100">
|
||||
<div class="row justify-content-center justify-content-md-start">
|
||||
<div class="col-12 col-md-6 my-3">
|
||||
{{ inner_header("Welcome, " ~ user.name ~ "!" ) }}
|
||||
</div>
|
||||
<div class="row justify-content-md-evenly">
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="card p-4 row">
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{%if messages %}
|
||||
{%if messages[0].category == FlashMessageCategory.PERSONAL_INFO %}
|
||||
<div class="col-12">{% include 'message.html' %}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<h5 class="card-title">Personal information</h5>
|
||||
<form class="needs-validation" method="post" novalidate>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="name">Name</label>
|
||||
<input
|
||||
class="form-control"
|
||||
disabled
|
||||
type="text"
|
||||
value="{{user.name}}"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="lastname">Lastname</label>
|
||||
<input
|
||||
class="form-control"
|
||||
disabled
|
||||
type="text"
|
||||
value="{{user.lastname}}"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="birthdate">Birthdate</label>
|
||||
<input
|
||||
class="form-control"
|
||||
disabled
|
||||
type="date"
|
||||
value="{{user.birth_date}}"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="phonenumber">Phone number</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="phonenumber"
|
||||
name="phonenumber"
|
||||
pattern="(\+\d{1,3}){0,1}[0-9]{7,255}"
|
||||
placeholder="Enter your phone number"
|
||||
required
|
||||
type="tel"
|
||||
value="{{user.phone_number}}"
|
||||
/>
|
||||
{{ form_field_validation(FORM_ERRORS['REQUIRED'] + " " +
|
||||
FORM_ERRORS['PHONE_NUMBER_FORMAT']) }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="email">Email</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="email"
|
||||
maxlength="255"
|
||||
name="email"
|
||||
pattern="[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$"
|
||||
placeholder="Enter your email address"
|
||||
required
|
||||
value="{{user.email}}"
|
||||
/>
|
||||
{{ form_field_validation(FORM_ERRORS['REQUIRED'] + " " +
|
||||
FORM_ERRORS['VALID_EMAIL']) }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="address">Address</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="address"
|
||||
maxlength="255"
|
||||
name="address"
|
||||
placeholder="1234 Main St"
|
||||
required
|
||||
type="text"
|
||||
value="{{user.address}}"
|
||||
/>
|
||||
{{ form_field_validation(FORM_ERRORS['REQUIRED']) }}
|
||||
</div>
|
||||
<input type="hidden" name="personal_information" value="true" />
|
||||
<div class="col-12 text-end mt-4">
|
||||
{{ form_submit_button("Submit") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-5">
|
||||
<div class="card p-4 row mt-4 mt-md-0">
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{%if messages %}
|
||||
{%if messages[0].category == FlashMessageCategory.PASSWORD %}
|
||||
<div class="col-12">{% include 'message.html' %}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<h5 class="card-title">Update password</h5>
|
||||
<form class="needs-validation" method="post" novalidate>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="password">Password</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="old_password"
|
||||
maxlength="255"
|
||||
minlength="6"
|
||||
name="password"
|
||||
placeholder="Enter current password"
|
||||
required
|
||||
type="password"
|
||||
/>
|
||||
{{ form_field_validation(FORM_ERRORS['REQUIRED'] + " " +
|
||||
FORM_ERRORS['PASSWORD_LENGTH']) }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="password">Password</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="password"
|
||||
maxlength="255"
|
||||
minlength="6"
|
||||
name="new_password"
|
||||
placeholder="Enter new password"
|
||||
required
|
||||
type="password"
|
||||
/>
|
||||
{{ form_field_validation(FORM_ERRORS['REQUIRED'] + " " +
|
||||
FORM_ERRORS['PASSWORD_LENGTH']) }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="password-confirmation"
|
||||
>Repeat new password</label
|
||||
>
|
||||
<input
|
||||
class="form-control"
|
||||
id="password-confirmation"
|
||||
maxlength="255"
|
||||
minlength="6"
|
||||
name="new_password_confirmation"
|
||||
placeholder="Repeat password"
|
||||
required
|
||||
type="password"
|
||||
/>
|
||||
{{ form_field_validation(FORM_ERRORS['REQUIRED'] + " " +
|
||||
FORM_ERRORS['PASSWORD_LENGTH'] + " " +
|
||||
FORM_ERRORS['MUST_MATCH_PASSWORD']) }}
|
||||
</div>
|
||||
<input type="hidden" name="password_update" value="true" />
|
||||
<div class="col-12 text-end mt-4">
|
||||
{{ form_submit_button("Submit") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="{{ url_for('static', filename='js/validate-form.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/passwords-match.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,10 +4,19 @@ from app.users import bp
|
||||
from app.utils.form_errors_dict import FORM_ERRORS
|
||||
from app.utils.helpers import login_required
|
||||
|
||||
@bp.route('/')
|
||||
@bp.route('/', methods=["GET", "POST"])
|
||||
@login_required
|
||||
def index():
|
||||
return render_template("users/index.html")
|
||||
user = UserService.get_user()
|
||||
if user is None:
|
||||
return redirect("login")
|
||||
user = user[0]
|
||||
if request.method == 'POST':
|
||||
if request.form.get("password_update"):
|
||||
UserService.update_password(request.form, user)
|
||||
elif request.form.get("personal_information"):
|
||||
UserService.update_personal_info(request.form, user)
|
||||
return render_template("users/index.html",user=user,FORM_ERRORS=FORM_ERRORS)
|
||||
|
||||
@bp.route('/login', methods=["GET", "POST"])
|
||||
def login():
|
||||
|
||||
Reference in New Issue
Block a user