#4 #6 Base creation of a product viewing page with the ability to edit as a seller

This commit is contained in:
Luke Else 2024-01-24 18:07:41 +00:00
parent 95768f8a8c
commit 0951bcc23e
10 changed files with 193 additions and 28 deletions

View File

@ -4,7 +4,7 @@ from models.products.product import Product
class ProductController(DatabaseController): class ProductController(DatabaseController):
FIELDS = ['id', 'name', 'image', 'description', 'cost', FIELDS = ['id', 'name', 'image', 'description', 'cost',
'category', 'sellerID', 'postedDate', 'quantityAvailable'] 'sellerID', 'category', 'postedDate', 'quantityAvailable']
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -131,8 +131,30 @@ class ProductController(DatabaseController):
return products return products
def update(self): def update(self, product: Product):
print("Doing work") params = [
product.name,
product.description,
product.image,
product.cost,
product.quantityAvailable,
product.category,
product.id
]
cursor = self._conn.execute(
"""UPDATE Products
SET name = ?,
description = ?,
image = ?,
cost = ?,
quantityAvailable = ?,
categoryID = ?
WHERE id = ?
""",
params
)
self._conn.commit()
def delete(self): def delete(self):
print("Doing work") print("Doing work")

View File

@ -69,12 +69,15 @@ def id(id: int):
# Check that a valid product was returned # Check that a valid product was returned
if product is None: if product is None:
flash("No Product available here") flash(f"No Product available with id {id}")
return redirect("/") return redirect("/")
print(product.name) print(product.name)
return render_template('index.html', content='content.html', products = [product]) return render_template(
return "ID: " + str(id) 'index.html',
content='product.html',
product=product
)
@blueprint.route('/add') @blueprint.route('/add')
@ -123,12 +126,44 @@ def add_product():
datetime.now(), datetime.now(),
request.form.get('quantity') request.form.get('quantity')
) )
db = ProductController() db = ProductController()
db.create(product) db.create(product)
return redirect('/products/ownproducts') return redirect('/products/ownproducts')
@blueprint.post('/update/<int:id>')
def update_product(id: int):
""" Processes a request to update a product in place on the site """
# Ensure that the product belongs to the current user
user_id = session.get('user_id')
# User needs to be logged in as a seller to view this page
if not is_role("Seller"):
flash("You must be logged in as a seller to view this page!")
return redirect("/")
db = ProductController()
product = db.read_id(id)
if product.sellerID != user_id:
flash("This product does not belong to you!")
return redirect("/ownproducts")
# Update product details
product.name = request.form.get('name')
product.description = request.form.get('description')
product.category = request.form.get('category')
product.image = request.form.get('image')
product.cost = request.form.get('cost')
product.quantityAvailable = request.form.get('quantity')
db.update(product)
flash("Product successfully updated")
return redirect(f"/{product.id}")
@blueprint.route('/ownproducts') @blueprint.route('/ownproducts')
def display_own_products(): def display_own_products():
""" Display products owned by the currently logged in seller """ """ Display products owned by the currently logged in seller """

View File

@ -2,7 +2,8 @@ h2 {
font-weight:300; font-weight:300;
text-align:center; text-align:center;
} }
#login-form-wrap {
#input-form-wrap {
background-color: rgba(255, 255, 255, .15); background-color: rgba(255, 255, 255, .15);
backdrop-filter: blur(200px); backdrop-filter: blur(200px);
width: 35%; width: 35%;
@ -11,7 +12,8 @@ h2 {
border-radius: 4px; border-radius: 4px;
box-shadow: 0px 30px 50px 0px rgba(0, 0, 0, 0.2); box-shadow: 0px 30px 50px 0px rgba(0, 0, 0, 0.2);
} }
.login-form {
.input-form {
padding: 1em 2em; padding: 1em 2em;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -19,7 +21,13 @@ h2 {
gap: 1em; gap: 1em;
} }
.login-form input, .login-form select, .login-form option { .input-form-row {
display: flex;
flex-direction: row;
gap: 1em 1em;
}
.input-form input, .input-form select, .input-form option, .input-form textarea {
width: 100%; width: 100%;
padding: 0 0 0 10px; padding: 0 0 0 10px;
margin: 0; margin: 0;
@ -48,7 +56,12 @@ h2 {
} }
} }
.login-form input[type="submit"] { .input-form textarea {
min-height: 120px;
max-width: 100%;
}
.input-form input[type="submit"] {
border: none; border: none;
display:block; display:block;
background-color: rgba(255, 255, 255, .10); background-color: rgba(255, 255, 255, .10);

View File

@ -42,12 +42,32 @@
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
flex: 4 0 1rem; flex: 4 0 1rem;
max-width: 40%;
padding: .5rem 1rem 2rem 2rem; padding: .5rem 1rem 2rem 2rem;
background: var(--bg-secondary); background: var(--bg-secondary);
border-radius: .5rem .5rem; border-radius: .5rem .5rem;
transition: all 0.2s; transition: all 0.2s;
} }
.product-fs {
height: 80%;
width: 80%;
font-size: 150%;
display: flex;
flex-direction: column;
justify-content: space-between;
flex-wrap: wrap;
padding: .5rem 1rem 2rem 2rem;
background: var(--bg-secondary);
border-radius: .5rem .5rem;
transition: all 0.2s;
}
.product-title {
font-size: 130%;
font-weight: bold;
}
.product-information { .product-information {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -4,7 +4,6 @@
<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/style.css')}}" /> <link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}" />
<link rel="stylesheet" href="{{url_for('static', filename='css/loginform.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

@ -1,6 +1,8 @@
<div id="login-form-wrap"> <link rel="stylesheet" href="{{url_for('static', filename='css/loginform.css')}}" />
<div id="input-form-wrap">
<h2>Login</h2> <h2>Login</h2>
<form class="login-form" method="POST"> <form class="input-form" method="POST">
<input type="text" id="username" name="username" placeholder="Username" required> <input type="text" id="username" name="username" placeholder="Username" required>
<input type="password" id="password" name="password" placeholder="Password" required> <input type="password" id="password" name="password" placeholder="Password" required>
<input type="submit" id="login" value="Login"> <input type="submit" id="login" value="Login">

View File

@ -1,16 +1,25 @@
<div id="login-form-wrap"> <link rel="stylesheet" href="{{url_for('static', filename='css/loginform.css')}}" />
<h2>Sign Up</h2>
<form class="login-form" method="POST" enctype="multipart/form-data"> <div id="input-form-wrap">
<h2>Create New Product</h2>
<form class="input-form" method="POST" enctype="multipart/form-data">
<div class="input-form-row">
<input type="text" id="name" name="name" placeholder="Product Name" required> <input type="text" id="name" name="name" placeholder="Product Name" required>
<input type="textarea" id="description" name="description" placeholder="Product Description" required>
<input type="file" id="image" name="image" accept="image/x" required> <input type="file" id="image" name="image" accept="image/x" required>
</div>
<textarea id="description" name="description" placeholder="Product Description" required></textarea>
<select name="category" id="category"> <select name="category" id="category">
{% for category in categories %} {% for category in categories %}
<option value="{{category.id}}">{{category.name}}</option> <option value="{{category.id}}">{{category.name}}</option>
{% endfor %} {% endfor %}
</select> </select>
<div class="input-form-row">
<input type="number" id="cost" name="cost" placeholder=10.99 min=0 step=any required> <input type="number" id="cost" name="cost" placeholder=10.99 min=0 step=any required>
<input type="number" id="quantity" name="quantity" placeholder=0 min=0 required> <input type="number" id="quantity" name="quantity" placeholder=0 min=0 required>
</div>
<input type="submit" id="Create Product" value="Create Product"> <input type="submit" id="Create Product" value="Create Product">
</form> </form>

57
templates/product.html Normal file
View File

@ -0,0 +1,57 @@
<link rel="stylesheet" href="{{ url_for('static', filename='css/products.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/loginform.css') }}">
<div class="product-fs">
{% if product != None %}
{% if user.id == product.sellerID%}
<form class="input-form" method="POST" action="/products/update/{{product.id}}" enctype="multipart/form-data">
<div class="product-title">
<input type="text" id="name" name="name" placeholder="Product Name" value="{{product.name}}" required>
</div>
<div class="product-information">
<div class="product-image">
<img src="{{url_for('static', filename='assets/img/products/' + product.image)}}" alt="Brake Disks" height="auto" width="150px" />
<input type="file" id="image" name="image" accept="image/x">
</div>
<div>
<div class="input-form-row">
<input type="number" id="cost" name="cost" placeholder=10.99 min=0 step=any value="{{product.cost}}"required>
<input type="textarea" id="description" name="description" placeholder="Product Description" value="{{product.description}}" required>
</div>
<div class="input-form-row">
<select name="category" id="category">
{% for category in categories %}
{% if category.id == product.category %}
<option value="{{category.id}}" selected>{{category.name}}</option>
{% else %}
<option value="{{category.id}}">{{category.name}}</option>
{% endif%}
{% endfor %}
</select>
</div>
<div class="input-form-row">
<input type="number" id="quantity" name="quantity" placeholder=0 min=0 value="{{product.quantityAvailable}}" required>
</div>
</div>
</div>
<input type="submit" id="Create Product" value="Create Product">
</form>
<div class="product-add-to-cart"></div>
{% else %}
<div class="product-title">{{product.name}}</div>
<div class="product-information">
<div class="product-image">
<img src="{{url_for('static', filename='assets/img/products/' + product.image)}}" alt="Brake Disks" height="auto" width="150px" />
</div>
<div class="product-details">
<div class="product-price">£{{product.cost}}</div>
<div class="product-description">{{product.description}}</div>
</div>
</div>
<div class="product-add-to-cart"></div>
{% endif %}
{% endif %}
</div>

View File

@ -1,10 +1,18 @@
<div id="login-form-wrap"> <link rel="stylesheet" href="{{url_for('static', filename='css/loginform.css')}}" />
<div id="input-form-wrap">
<h2>Sign Up</h2> <h2>Sign Up</h2>
<form class="login-form" method="POST"> <form class="input-form" method="POST">
<div class="input-form-row">
<input type="text" id="firstname" name="firstname" placeholder="First Name" required> <input type="text" id="firstname" name="firstname" placeholder="First Name" required>
<input type="text" id="lastname" name="lastname" placeholder="Last Name" required> <input type="text" id="lastname" name="lastname" placeholder="Last Name" required>
</div>
<div class="input-form-row">
<input type="text" id="username" name="username" placeholder="Username" required> <input type="text" id="username" name="username" placeholder="Username" required>
<input type="email" id="email" name="email" placeholder="Email Address" required> <input type="email" id="email" name="email" placeholder="Email Address" required>
</div>
<input type="password" id="password" name="password" minlength=8 placeholder="Password" required> <input type="password" id="password" name="password" minlength=8 placeholder="Password" required>
<label class="checkbox">Signup as a Seller? <label class="checkbox">Signup as a Seller?
<input type="checkbox" id="seller" name="seller"/> <input type="checkbox" id="seller" name="seller"/>