#10 Added ability to update user details
This commit is contained in:
parent
d6f7b3e549
commit
3b8be99e15
@ -69,8 +69,29 @@ class UserController(DatabaseController):
|
||||
|
||||
return self.get_many(query, params)
|
||||
|
||||
def update(self):
|
||||
print("Doing work")
|
||||
def update(self, user: User):
|
||||
params = [
|
||||
user.username,
|
||||
user.firstName,
|
||||
user.lastName,
|
||||
user.email,
|
||||
user.phone,
|
||||
user.role,
|
||||
user.id
|
||||
]
|
||||
|
||||
query = """
|
||||
UPDATE Users
|
||||
SET username = ?,
|
||||
first_name = ?,
|
||||
last_name = ?,
|
||||
email = ?,
|
||||
phone = ?,
|
||||
role = ?
|
||||
WHERE id = ?
|
||||
"""
|
||||
|
||||
return self.do(query, params)
|
||||
|
||||
def delete(self, id: int):
|
||||
params = [
|
||||
|
@ -7,12 +7,27 @@ from flask import render_template, redirect, request, session, flash, url_for
|
||||
from controllers.database.user import UserController
|
||||
from models.users.customer import Customer
|
||||
from models.users.seller import Seller
|
||||
from models.users.user import User
|
||||
from utils.user_utils import is_role
|
||||
from hashlib import sha512
|
||||
|
||||
# Blueprint to append user endpoints to
|
||||
blueprint = Blueprint("users", __name__, url_prefix="/users")
|
||||
|
||||
ROLES = [
|
||||
"Customer",
|
||||
"Seller",
|
||||
"Admin"
|
||||
]
|
||||
|
||||
|
||||
@blueprint.context_processor
|
||||
def roles_list():
|
||||
""" Places a list of all the available roles in the
|
||||
users context
|
||||
"""
|
||||
return dict(roles=ROLES)
|
||||
|
||||
|
||||
# LOGIN FUNCTIONALITY
|
||||
@blueprint.route('/login')
|
||||
@ -44,6 +59,62 @@ def login():
|
||||
return redirect(url_for('main.index'))
|
||||
|
||||
|
||||
# SIGNUP FUNCTIONALITY
|
||||
@blueprint.route('/update/<int:id>')
|
||||
def display_update(id: int):
|
||||
""" Function responsible for delivering the Update User page
|
||||
for the site
|
||||
"""
|
||||
db = UserController()
|
||||
user = db.read_id(id)
|
||||
|
||||
return render_template('index.html', content="user.html", user=user)
|
||||
|
||||
|
||||
@blueprint.post('/update/<int:id>')
|
||||
def update(id: int):
|
||||
""" Function to handle the backend processing of a signup request """
|
||||
if not is_role("Admin"):
|
||||
flash("You must be logged in an admin to update users!", "error")
|
||||
return redirect(url_for('main.index'))
|
||||
|
||||
user = User(
|
||||
request.form['username'],
|
||||
"", # Password
|
||||
request.form['firstname'],
|
||||
request.form['lastname'],
|
||||
request.form['email'],
|
||||
request.form['phone'],
|
||||
request.form['role'],
|
||||
)
|
||||
|
||||
user.id = id
|
||||
|
||||
db = UserController()
|
||||
checking_user = db.read(user.username)
|
||||
|
||||
# User with this new username is already taken
|
||||
if checking_user is not None and checking_user.id != user.id:
|
||||
flash(
|
||||
f"User with the username {user.username} already exists!",
|
||||
"warning"
|
||||
)
|
||||
return redirect(url_for('main.users.display_update', id=id))
|
||||
|
||||
db.update(user)
|
||||
|
||||
return redirect(url_for('main.admin.users'))
|
||||
|
||||
|
||||
# SIGN OUT FUNCTIONALITY
|
||||
@blueprint.route('/logout')
|
||||
def logout():
|
||||
""" Function responsible for handling logouts from the site """
|
||||
# Clear the current user from the session if they are logged in
|
||||
session.pop('user_id', None)
|
||||
return redirect(url_for('main.index'))
|
||||
|
||||
|
||||
# SIGNUP FUNCTIONALITY
|
||||
@blueprint.route('/signup')
|
||||
def display_signup():
|
||||
@ -85,20 +156,10 @@ def signup():
|
||||
)
|
||||
|
||||
database.create(user)
|
||||
|
||||
# Code 307 Preserves the original request (POST)
|
||||
return redirect(url_for('main.users.login'), code=307)
|
||||
|
||||
|
||||
# SIGN OUT FUNCTIONALITY
|
||||
@blueprint.route('/logout')
|
||||
def logout():
|
||||
""" Function responsible for handling logouts from the site """
|
||||
# Clear the current user from the session if they are logged in
|
||||
session.pop('user_id', None)
|
||||
return redirect(url_for('main.index'))
|
||||
|
||||
|
||||
# DELETE USER FUNCTIONALITY
|
||||
@blueprint.post('/delete/<int:id>')
|
||||
def delete(id: int):
|
||||
|
@ -3,7 +3,16 @@ h2 {
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#input-form-wrap {
|
||||
#form-footer {
|
||||
background-color: rgba(255, 255, 255, .15);
|
||||
color:#dfdfdf;
|
||||
font-size:14px;
|
||||
width:100%;
|
||||
padding:10px 0;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
#form-wrapper {
|
||||
background-color: rgba(255, 255, 255, .15);
|
||||
backdrop-filter: blur(200px);
|
||||
width: 35%;
|
||||
@ -21,14 +30,14 @@ h2 {
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.input-form-row {
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
gap: 1em 1em;
|
||||
}
|
||||
|
||||
.input-form-row input, .input-form-row select, .input-form-row option, .input-form-row textarea {
|
||||
.form-row input, .form-row select, .form-row option, .form-row textarea {
|
||||
width: 100%;
|
||||
padding: 0 0 0 10px;
|
||||
margin: 0;
|
||||
@ -57,12 +66,12 @@ h2 {
|
||||
}
|
||||
}
|
||||
|
||||
.input-form-row textarea {
|
||||
.form-row textarea {
|
||||
min-height: 120px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.input-form-row input[type="submit"] {
|
||||
.form-row input[type="submit"] {
|
||||
border: none;
|
||||
display:block;
|
||||
background-color: rgba(255, 255, 255, .10);
|
||||
@ -81,14 +90,6 @@ h2 {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
}
|
||||
#create-account-wrap {
|
||||
background-color: rgba(255, 255, 255, .15);
|
||||
color:#dfdfdf;
|
||||
font-size:14px;
|
||||
width:100%;
|
||||
padding:10px 0;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
display: block;
|
@ -1,5 +1,5 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/admin.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/modal.css') }}">
|
||||
|
||||
<!-- USER MANAGEMENT-->
|
||||
@ -26,13 +26,15 @@
|
||||
<td>{{user.phone}}</td>
|
||||
<td>{{user.role}}</td>
|
||||
<td>
|
||||
<div class="input-form-row">
|
||||
<div class="button neutral">
|
||||
<p class="btnText">Edit User</p>
|
||||
<div class="btnTwo">
|
||||
<p class="btnText2">{{user.id}}</p>
|
||||
<div class="form-row">
|
||||
<a href="{{ url_for('main.users.display_update', id=user.id) }}">
|
||||
<div class="button neutral">
|
||||
<p class="btnText">Edit User</p>
|
||||
<div class="btnTwo">
|
||||
<p class="btnText2">{{user.id}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<label for="deleteModal{{user.id}}">
|
||||
<div class="button error">
|
||||
<p class="btnText">DELETE USER</p>
|
||||
@ -54,7 +56,7 @@
|
||||
<h2>Confirm Delete</h2>
|
||||
<p>Are you sure you want to <b>delete</b> {{user.role}} <b>{{user.username}}</b></p>
|
||||
<form method="POST" action="{{ url_for('main.users.delete', id=user.id) }}">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" class="modal-btn error" for="deleteModal{{user.id}}" value="Delete" />
|
||||
</div>
|
||||
</form>
|
||||
@ -92,7 +94,7 @@
|
||||
<td>{{product.category}}</td>
|
||||
<td>{{product.quantityAvailable}}</td>
|
||||
<td>
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<a href="{{url_for('main.products.product', id=product.id)}}">
|
||||
<div class="button neutral">
|
||||
<p class="btnText">Edit Product</p>
|
||||
@ -122,7 +124,7 @@
|
||||
<h2>Confirm Delete</h2>
|
||||
<p>Are you sure you want to <b>delete</b> <b>{{product.name}}</b></p>
|
||||
<form method="POST" action="{{ url_for('main.seller.delete', id=product.id) }}">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" class="modal-btn error" for="deleteModal{{product.id}}" value="Delete" />
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" />
|
||||
|
||||
<div id="input-form-wrap">
|
||||
<div id="form-wrapper">
|
||||
<h2>Login</h2>
|
||||
<form class="input-form" method="POST" action="{{ url_for('main.users.login') }}">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="text" id="username" name="username" placeholder="Username" required>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="password" id="password" name="password" placeholder="Password" required>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" id="login" value="Login">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="create-account-wrap">
|
||||
<div id="form-footer">
|
||||
<p>Not a member? <a href="{{ url_for('main.users.display_signup') }}">Create Account</a><p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,18 +1,18 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" />
|
||||
|
||||
<div id="input-form-wrap">
|
||||
<div id="form-wrapper">
|
||||
<h2>Create New Product</h2>
|
||||
<form class="input-form" method="POST" action="{{ url_for('main.seller.add') }}" enctype="multipart/form-data">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="text" id="name" name="name" placeholder="Product Name" required>
|
||||
<input type="file" id="image" name="image" accept="image/x" required>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<textarea id="description" name="description" placeholder="Product Description" required></textarea>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<select name="category" id="category">
|
||||
{% for category in categories %}
|
||||
<option value="{{category.id}}">{{category.name}}</option>
|
||||
@ -20,17 +20,17 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="number" id="cost" name="cost" placeholder="Cost" min=0 step=0.01 required>
|
||||
<input type="number" id="quantity" name="quantity" placeholder="Quantity Available" min=0 required>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" id="Create Product" value="Create Product">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="create-account-wrap">
|
||||
<div id="form-footer">
|
||||
<p>Want to view all of your products? <a href="{{ url_for('main.seller.display_own') }}">Click Here</a><p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/products.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}">
|
||||
|
||||
{% if product != None %}
|
||||
{% if user.id == product.sellerID or user.role == "Admin" %}
|
||||
@ -7,14 +7,14 @@
|
||||
<form class="product-fs" method="POST" action="{{ url_for('main.seller.update', id=product.id) }}" enctype="multipart/form-data">
|
||||
<img class="product-image" src="{{ url_for('static', filename='assets/img/products/' + product.image) }}" alt="Brake Disks"/>
|
||||
<div class="product-details">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="text" id="name" name="name" placeholder="Product Name" value="{{product.name}}" required>
|
||||
</div>
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<textarea id="description" name="description" placeholder="Product Description" required>{{product.description}}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<select name="category" id="category">
|
||||
{% for category in categories %}
|
||||
{% if category.id == product.category %}
|
||||
@ -26,11 +26,11 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="file" id="image" name="image" accept="image/x">
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" id="Create Product" value="Update Product">
|
||||
</div>
|
||||
|
||||
@ -44,21 +44,21 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="product-acquisition-pane">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="number" id="cost" name="cost" placeholder="Cost" min=0 step=0.01 value="{{product.cost}}"required>
|
||||
</div>
|
||||
<div class="product-delivery">Earliest Delivery Friday 24th December</div>
|
||||
<div class="product-postage">+£{{product.cost}} P&P</div>
|
||||
<div class="product-stock">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="number" id="quantity" name="quantity" placeholder="Quantity Available" min=0 value="{{product.quantityAvailable}}" required>
|
||||
</div>
|
||||
{% if product.quantityAvailable > 0 %}
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<div class="product-instock">In Stock</div>
|
||||
<div class="product-quantity">{{product.quantityAvailable}} Available</div>
|
||||
</div>
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<a href="{{ url_for('main.stats.view_product_stats', id=product.id) }}">
|
||||
<div class="button success">
|
||||
<p class="btnText">VIEW STATS</p>
|
||||
@ -84,7 +84,7 @@
|
||||
<h2>Confirm Delete</h2>
|
||||
<p>Are you sure you want to <b>delete {{product.name}}</b> from your products</p>
|
||||
<form method="POST" action="{{ url_for('main.seller.delete', id=product.id) }}">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" class="modal-btn error" for="deleteModal" value="Delete" />
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,19 +1,19 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" />
|
||||
|
||||
<div id="input-form-wrap">
|
||||
<div id="form-wrapper">
|
||||
<h2>Sign Up</h2>
|
||||
<form class="input-form" action="{{ url_for('main.users.signup') }}" method="POST">
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="text" id="firstname" name="firstname" placeholder="First Name" required>
|
||||
<input type="text" id="lastname" name="lastname" placeholder="Last Name" required>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="text" id="username" name="username" placeholder="Username" required>
|
||||
<input type="email" id="email" name="email" placeholder="Email Address" required>
|
||||
</div>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="password" id="password" name="password" minlength=8 placeholder="Password" required>
|
||||
</div>
|
||||
|
||||
@ -22,12 +22,12 @@
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<input type="submit" id="Sign Up" value="Sign Up">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="create-account-wrap">
|
||||
<div id="form-footer">
|
||||
<p>Already have an account? <a href="{{ url_for('main.users.display_login') }}">Login</a><p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/products.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/stats.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}">
|
||||
|
||||
<div class="stats">
|
||||
<div>
|
||||
<canvas id="myChart" width="800px" height="500px"></canvas>
|
||||
<br >
|
||||
<div class="input-form-row">
|
||||
<div class="form-row">
|
||||
<a href="?prev_days=7">1 Week</a>
|
||||
<a href="?prev_days=14">2 Weeks</a>
|
||||
<a href="?prev_days=31">1 Month</a>
|
||||
|
44
templates/user.html
Normal file
44
templates/user.html
Normal file
@ -0,0 +1,44 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" />
|
||||
|
||||
<div id="form-wrapper">
|
||||
<h2>Update User</h2>
|
||||
{% if user != None %}
|
||||
<form class="input-form" action="{{ url_for('main.users.update', id=user.id) }}" method="POST">
|
||||
<div class="form-row">
|
||||
<input type="text" id="firstname" name="firstname" placeholder="First Name" value="{{user.firstName}}" required>
|
||||
<input type="text" id="lastname" name="lastname" placeholder="Last Name" value="{{user.lastName}}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<input type="text" id="username" name="username" placeholder="Username" value="{{user.username}}" required>
|
||||
<input type="email" id="email" name="email" placeholder="Email Address" value="{{user.email}}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<input type="tel" id="phone" name="phone" placeholder="Telephone Number" value="{{user.phone}}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<select name="role" id="role">
|
||||
{% for role in roles %}
|
||||
{% if role == user.role %}
|
||||
<option value="{{role}}" selected>{{role}}</option>
|
||||
{% else %}
|
||||
<option value="{{role}}">{{role}}</option>
|
||||
{% endif%}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<input type="submit" id="Update" value="Update User">
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>No user found with the given ID.</p>
|
||||
{% endif %}
|
||||
|
||||
<div id="form-footer">
|
||||
<p>Already have an account? <a href="{{ url_for('main.users.display_login') }}">Login</a><p>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user