#10 Added ability for users to be removed from the site.

This commit is contained in:
Luke Else 2024-02-13 22:48:23 +00:00
parent d6244223c4
commit 3dc7a1f861
11 changed files with 182 additions and 20 deletions

View File

@ -72,5 +72,10 @@ class UserController(DatabaseController):
def update(self): def update(self):
print("Doing work") print("Doing work")
def delete(self): def delete(self, id: int):
print("Doing work") params = [
id
]
query = """ DELETE FROM Users WHERE id = ? """
return self.do(query, params)

View File

@ -11,13 +11,13 @@ blueprint = Blueprint("admin", __name__, url_prefix="/admin")
@blueprint.route('/') @blueprint.route('/')
def main_admin(): def main():
""" Function responsible for delivering the admin page for the site """ """ Function responsible for delivering the admin page for the site """
return "Hello, World" return "Hello, World"
@blueprint.route('/users/') @blueprint.route('/users/')
def admin_users(): def users():
""" Endpoint responsible for managing a users permissions """ """ Endpoint responsible for managing a users permissions """
# Get all users to create admin table on frontend # Get all users to create admin table on frontend
db = UserController() db = UserController()

View File

@ -7,6 +7,7 @@ from flask import render_template, redirect, request, session, flash
from controllers.database.user import UserController from controllers.database.user import UserController
from models.users.customer import Customer from models.users.customer import Customer
from models.users.seller import Seller from models.users.seller import Seller
from utils.user_utils import is_role
from hashlib import sha512 from hashlib import sha512
# Blueprint to append user endpoints to # Blueprint to append user endpoints to
@ -96,3 +97,16 @@ def logout():
# Clear the current user from the session if they are logged in # Clear the current user from the session if they are logged in
session.pop('user_id', None) session.pop('user_id', None)
return redirect("/") return redirect("/")
# DELETE USER FUNCTIONALITY
@blueprint.post('/delete/<int:id>')
def delete(id: int):
""" Function responsible for deleting users from the site """
if not is_role("Admin"):
flash("You must be logged in an admin to remove users!", "error")
return redirect("/")
db = UserController()
db.delete(id)
return redirect("/admin/users/")

View File

@ -1,6 +1,6 @@
INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "luke-else", "test@test.com", "07498 289321", "cbe0cd68cbca3868250c0ba545c48032f43eb0e8a5e6bab603d109251486f77a91e46a3146d887e37416c6bdb6cbe701bd514de778573c9b0068483c1c626aec", "Seller");
INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "test-customer", "test@test.net", "07498 289322", "cbe0cd68cbca3868250c0ba545c48032f43eb0e8a5e6bab603d109251486f77a91e46a3146d887e37416c6bdb6cbe701bd514de778573c9b0068483c1c626aec", "Customer");
INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "test-seller", "test@test.not", "07498 289323", "cbe0cd68cbca3868250c0ba545c48032f43eb0e8a5e6bab603d109251486f77a91e46a3146d887e37416c6bdb6cbe701bd514de778573c9b0068483c1c626aec", "Seller"); INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "test-seller", "test@test.not", "07498 289323", "cbe0cd68cbca3868250c0ba545c48032f43eb0e8a5e6bab603d109251486f77a91e46a3146d887e37416c6bdb6cbe701bd514de778573c9b0068483c1c626aec", "Seller");
INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "test-customer", "test@test.net", "07498 289322", "cbe0cd68cbca3868250c0ba545c48032f43eb0e8a5e6bab603d109251486f77a91e46a3146d887e37416c6bdb6cbe701bd514de778573c9b0068483c1c626aec", "Customer");
INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "luke-else", "test@test.com", "07498 289321", "cbe0cd68cbca3868250c0ba545c48032f43eb0e8a5e6bab603d109251486f77a91e46a3146d887e37416c6bdb6cbe701bd514de778573c9b0068483c1c626aec", "Admin");
INSERT INTO Products (name, image, description, cost, sellerID, categoryID, quantityAvailable, postedDate) VALUES ("12' Brake Disks", "brake-disks.bmp", "this is a product", 20.99, 1, 1, 10, datetime()); INSERT INTO Products (name, image, description, cost, sellerID, categoryID, quantityAvailable, postedDate) VALUES ("12' Brake Disks", "brake-disks.bmp", "this is a product", 20.99, 1, 1, 10, datetime());
INSERT INTO Products (name, image, description, cost, sellerID, categoryID, quantityAvailable, postedDate) VALUES ("Exhaust Manifold", "manifold.bmp", "This is a super cool product that can be installed into your car to take the gasses from the inside all the way to the outside. Mad I know.", 20.99, 1, 1, 9, datetime()); INSERT INTO Products (name, image, description, cost, sellerID, categoryID, quantityAvailable, postedDate) VALUES ("Exhaust Manifold", "manifold.bmp", "This is a super cool product that can be installed into your car to take the gasses from the inside all the way to the outside. Mad I know.", 20.99, 1, 1, 9, datetime());

66
static/css/buttons.css Normal file
View File

@ -0,0 +1,66 @@
@import url(https://fonts.googleapis.com/css?family=Roboto:700);
:root {
--btn-width: 100%;
}
.button {
font-size: medium;
font-weight: bold;
width : var(--btn-width);
height : 50px;
overflow: hidden;
text-align : center;
transition : .2s;
cursor : pointer;
border-radius: 3px;
box-shadow: 0px 1px 2px rgba(0,0,0,.2);
}
.btnTwo {
position : relative;
width : 200px;
height : 100px;
margin-top: -100px;
padding-top: 2px;
background : rgba(0, 0, 0, 0.1);
left : -250px;
transition : .3s;
}
.btnText {
color : white;
transition : .3s;
}
.btnText2 {
margin-top : 63px;
margin-right : -130px;
color : #FFF;
}
.button:hover .btnTwo{ /*When hovering over .button change .btnTwo*/
left: -130px;
}
.button:hover .btnText{ /*When hovering over .button change .btnText*/
margin-left : 65px;
}
.button:active { /*Clicked and held*/
box-shadow: 0px 5px 6px rgba(0,0,0,0.3);
}
.button.error {
background-color: var(--red);
}
.button.success {
background: var(--green);
}
.button.info {
background-color: #2879c550;
}
.button.wmgzon {
background-color: orange;
}
.button.neutral {
background-color: rgba(0, 0, 0, 0.3);
}

View File

@ -96,6 +96,10 @@
gap: 1rem 1rem; gap: 1rem 1rem;
} }
.product-selection {
width: 60%;
}
.product-description { .product-description {
font-size: 70%; font-size: 70%;
} }
@ -140,6 +144,7 @@
justify-content: space-around; justify-content: space-around;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
gap: .5em;
} }
.product-quantity { .product-quantity {
font-size: 50%; font-size: 50%;

View File

@ -1,4 +1,6 @@
<link rel="stylesheet" href="{{ url_for('static', filename='css/admin.css') }}"> <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/modal.css') }}">
{% if users != None %} {% if users != None %}
<p>Showing {{users|count}} users</p> <p>Showing {{users|count}} users</p>
@ -6,20 +8,57 @@
<table class="table table-style"> <table class="table table-style">
<thead> <thead>
<tr> <tr>
<th scope="col">#</th>
<th scope="col">Username</th> <th scope="col">Username</th>
<th scope="col">E-Mail</th> <th scope="col">E-Mail</th>
<th scope="col">Phone Number</th> <th scope="col">Phone Number</th>
<th>BUTTON</th> <th scope="col">Role</th>
<th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for user in users %} {% for user in users %}
<tr> <tr>
<td>{{user.id}}</td>
<td>{{user.username}}</td> <td>{{user.username}}</td>
<td>{{user.email}}</td> <td>{{user.email}}</td>
<td>{{user.phone}}</td> <td>{{user.phone}}</td>
<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>
</div>
<label for="deleteModal{{user.id}}">
<div class="button error">
<p class="btnText">DELETE USER</p>
<div class="btnTwo">
<p class="btnText2">X</p>
</div>
</div>
</label>
</div>
</td>
</tr> </tr>
<!-- Modal -->
<input class="modal-state" id="deleteModal{{user.id}}" type="checkbox" />
<div class="modal">
<label class="modal__bg" for="deleteModal{{user.id}}"></label>
<div class="modal__inner">
<label class="modal__close" for="deleteModal{{user.id}}"></label>
<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">
<input type="submit" class="modal-btn error" for="deleteModal{{user.id}}" value="Delete" />
</div>
</form>
</div>
</div>
<!-- <a href="/products/{{user.id}}" class="product product-link"> <!-- <a href="/products/{{user.id}}" class="product product-link">
<div class="product-title">{{user.username}}</div> <div class="product-title">{{user.username}}</div>
<div class="product-content-container"> <div class="product-content-container">

View File

@ -14,7 +14,14 @@
<div class="product-description hide-overflow ">{{product.description}}</div> <div class="product-description hide-overflow ">{{product.description}}</div>
</div> </div>
</div> </div>
<input type="submit" class="product-add-to-cart" value="Add to Cart" /> <div class="product-selection">
<div class="button wmgzon">
<p class="btnText">ADD TO BASKET</p>
<div class="btnTwo">
<p class="btnText2">:)</p>
</div>
</div>
</div>
</a> </a>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -15,13 +15,21 @@
</div> </div>
</nav> </nav>
{% if user != None and user.role == "Seller" %} {% if user != None %}
{% if user.role == "Seller" %}
<div class="categories"> <div class="categories">
{# List all available seller tools #} {# List all available Seller tools #}
<a href="{{url_for('main.products.display_add_product')}}" class="category">Create Products</a> <a href="{{url_for('main.products.display_add_product')}}" class="category">Create Products</a>
<a href="{{url_for('main.products.display_own_products')}}" class="category">View My Products</a> <a href="{{url_for('main.products.display_own_products')}}" class="category">View My Products</a>
<a href="{{url_for('main.stats.index')}}" class="category">View Seller Stats</a> <a href="{{url_for('main.stats.index')}}" class="category">View Seller Stats</a>
</div> </div>
{% elif user.role == "Admin" %}
<div class="categories">
{# List all available Admin tools #}
<a href="{{url_for('main.admin.users')}}" class="category">Manage Users</a>
<a href="{{url_for('main.admin.main')}}" class="category">Manage Products</a>
</div>
{% endif %}
{% endif %} {% endif %}
<div class="categories"> <div class="categories">

View File

@ -3,6 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{url_for('static', filename='css/buttons.css')}}" />
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}" /> <link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}" />
<link rel="stylesheet" href="{{url_for('static', filename='css/alerts.css')}}" /> <link rel="stylesheet" href="{{url_for('static', filename='css/alerts.css')}}" />
<link href="http://fonts.cdnfonts.com/css/uk-number-plate" rel="stylesheet"> <link href="http://fonts.cdnfonts.com/css/uk-number-plate" rel="stylesheet">

View File

@ -33,7 +33,15 @@
<div class="input-form-row"> <div class="input-form-row">
<input type="submit" id="Create Product" value="Update Product"> <input type="submit" id="Create Product" value="Update Product">
</div> </div>
<label class="modal-btn" for="deleteModal">Delete Product</label>
<label for="deleteModal">
<div class="button error">
<p class="btnText">DELETE PRODUCT</p>
<div class="btnTwo">
<p class="btnText2">X</p>
</div>
</div>
</label>
</div> </div>
<div class="product-acquisition-pane"> <div class="product-acquisition-pane">
<div class="input-form-row"> <div class="input-form-row">
@ -46,11 +54,20 @@
<input type="number" id="quantity" name="quantity" placeholder="Quantity Available" min=0 value="{{product.quantityAvailable}}" required> <input type="number" id="quantity" name="quantity" placeholder="Quantity Available" min=0 value="{{product.quantityAvailable}}" required>
</div> </div>
{% if product.quantityAvailable > 0 %} {% if product.quantityAvailable > 0 %}
<div class="input-form-row">
<div class="product-instock">In Stock</div> <div class="product-instock">In Stock</div>
<div class="product-quantity">{{product.quantityAvailable}} Available</div> <div class="product-quantity">{{product.quantityAvailable}} Available</div>
</div>
<div class="input-form-row">
<a href="{{url_for('main.stats.view_product_stats', id=product.id)}}"> <a href="{{url_for('main.stats.view_product_stats', id=product.id)}}">
<input type="button" class="product-add-to-cart" value="View Product Stats"/> <div class="button success">
<p class="btnText">VIEW STATS</p>
<div class="btnTwo">
<p class="btnText2">!!!</p>
</div>
</div>
</a> </a>
</div>
{% else %} {% else %}
<div class="product-nostock">Out of Stock</div> <div class="product-nostock">Out of Stock</div>
{% endif %} {% endif %}