diff --git a/store/forms.py b/store/forms.py index 25f984179f9616a7248a77c13fb064719386763f..7daa55392a7be29d6814f23a575b4b1c64f0ae99 100644 --- a/store/forms.py +++ b/store/forms.py @@ -6,24 +6,36 @@ from wtforms import ( SubmitField, SelectField, IntegerField, + SearchField, + EmailField, + TelField, + DecimalField, + TextAreaField, validators, ) -from wtforms.validators import DataRequired # Basic example.# +import datetime class RegistrationForm(FlaskForm): - username = StringField("Username", [validators.Length(min=4, max=255)]) - email = StringField("Email Address", [validators.Length(min=6, max=255)]) - phone_number = StringField("Phone Number", [validators.Length(min=6, max=35)]) + username = StringField( + "Username", [validators.DataRequired(), validators.Length(max=256)] + ) + email = EmailField( + "Email Address", [validators.DataRequired(), validators.Length(max=256)] + ) + phone_number = TelField("Phone Number", [validators.DataRequired()]) password = PasswordField( "New Password", [ - validators.DataRequired(), + validators.InputRequired(), validators.EqualTo("confirm", message="Passwords must match"), - validators.Length(min=6, max=220), + validators.Length(min=6), ], ) - confirm = PasswordField("Repeat Password") + confirm = PasswordField( + "Repeat Password", + validators=[validators.DataRequired(), validators.EqualTo("password")], + ) accept_tos = BooleanField( "I accept the Terms of Service", [validators.DataRequired()] ) @@ -31,13 +43,16 @@ class RegistrationForm(FlaskForm): class LoginForm(FlaskForm): - username = StringField("Username", [validators.Length(min=4, max=255)]) - password = PasswordField("Password", [validators.Length(min=6, max=220)]) + username = StringField("Username") + password = PasswordField("Password") + securityQ1 = StringField("Enter your Favourite Colour", [validators.Length(max=30)]) submit = SubmitField("Login", render_kw={"class": "button"}) class SearchForm(FlaskForm): - query = StringField("Query", [validators.DataRequired()]) + query = SearchField( + "Search", [validators.DataRequired()], render_kw={"placeholder": "Search"} + ) submit = SubmitField("Submit") @@ -54,6 +69,5 @@ class AddForm(FlaskForm): "Table", choices=["Item", "Item Set"], validators=[validators.DataRequired()] ) description = StringField("Description", validators=[validators.DataRequired()]) - # Default value so item set doesn't have validation errors despite not needing it. - price = IntegerField(default=0, validators=[validators.DataRequired()]) + price = IntegerField(default=0, validators=[validators.InputRequired()]) submit = SubmitField("Submit") diff --git a/store/models.py b/store/models.py index 5927166f2fd7082bb0945b96428b3dd6282e2ccb..05b98c7cc16e8c5c99a0c5cba7c79d661df30c44 100644 --- a/store/models.py +++ b/store/models.py @@ -87,6 +87,9 @@ class User(db.Model, UserMixin): username = db.Column(db.String(256), nullable=False, unique=True) email = db.Column(db.String(256), nullable=False) phone_number = db.Column(db.String(20), nullable=False) + # The hashing algorithm determines how much storage is taken in the databasse, + # as the password itself can be of a theoretically infinite length but hashed + # into a sepcific size. password_hash = db.Column(db.String(256), nullable=False) userType = db.Column(db.String(20), default="standard") diff --git a/store/routes.py b/store/routes.py index 9d64c8741dcbaf5fa7a556795b71b408bb97705c..8ac45a32128f3f28efeb968a670d9b39c6790f63 100644 --- a/store/routes.py +++ b/store/routes.py @@ -80,8 +80,9 @@ def get_user_id(): @app.route("/") @app.route("/index") def index(): + repositories = Repository.query.all() # If the title is unspecified then a default is used that is set in base.html - return render_template("index.html", title="Home") + return render_template("index.html", title="Home", repositories=repositories) @app.route("/items") @@ -94,26 +95,25 @@ def items(): @app.route("/item_sets") def item_sets(): items = get_item_sets() - return render_template("item_sets.html", title="Item Sets", items=items) + return render_template("items.html", title="Item Sets", items=items) -@app.route("/item_set_page/<int:item_id>") +@app.route("/item_<int:item_id>") +def item_page(item_id): + item = get_item_by_id(item_id) + if not item: + return "Item not found", 404 + + return render_template("item_page.html", item=item) + + +@app.route("/item_set_<int:item_id>") def item_set_page(item_id): item = get_item_set_by_id(item_id) if not item: return "Item set not found", 404 - item_price = item.price - item_description = item.description - print(item.items) - contained_items = item.items - return render_template( - "item_set_page.html", - item_price=item_price, - item_description=item_description, - item_id=item_id, - contained_items=contained_items, - ) + return render_template("item_page.html", item=item) @app.route("/register", methods=["POST", "GET"]) @@ -284,14 +284,6 @@ def account(): return redirect(url_for("index")) -@app.route("/accountDetails") -@login_required -def accountDetails(): - a = get_user_id() - user = User.query.filter_by(user_id=a).first() - return render_template("userContent/accountDetails.html", user=user) - - @app.route("/standardUser") @login_required def standardUser(): @@ -299,7 +291,9 @@ def standardUser(): flash("Unauthorized access no admins allowed please create a standard account") return redirect(url_for("home")) else: - return render_template("userContent/user.html") + return render_template( + "userContent/user.html", user=current_user, userType=current_user.userType + ) @app.route("/admin") @@ -309,7 +303,9 @@ def admin(): flash("Unauthorized access") return redirect(url_for("home")) else: - return render_template("userContent/admin.html") + return render_template( + "userContent/user.html", user=current_user, userType=current_user.userType + ) @app.route("/database_management", methods=["GET", "POST"]) @@ -703,21 +699,6 @@ def remove_item_basket(): # Calling this remove_item shadows the utility functi return redirect(url_for("basket")) -@app.route("/item_page/<int:item_id>") -def item_page(item_id): - item = get_item_by_id(item_id) - if not item: - return "Item not found", 404 - item_price = item.price - item_description = item.description - return render_template( - "item_page.html", - item_price=item_price, - item_description=item_description, - item_id=item_id, - ) - - @app.route("/addAdress", methods=["GET", "POST"]) @login_required def addAdress(): @@ -774,4 +755,4 @@ def search(): form = SearchForm() if form.validate_on_submit(): items = get_by_keyword(form.query.data) - return render_template("search.html", form=form, items=items) + return render_template("items.html", items=items) diff --git a/store/static/_main.css b/store/static/_main.css index 4376306f01243e36ee6fdb8daef6548a6c7a699d..1b3d82142cf2c47ca433a30ca35415d659e66c09 100644 --- a/store/static/_main.css +++ b/store/static/_main.css @@ -1,280 +1,39 @@ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) - - Reseting css for all browsers in order - to look the same for each browser the - user is going to use - - Alfret Imeri -*/ - -html, -body, -div, -span, -applet, -object, -iframe, -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -big, -cite, -code, -del, -dfn, -em, -img, -ins, -kbd, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -b, -u, -i, -center, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td, -article, -aside, -canvas, -details, -embed, -figure, -figcaption, -footer, -header, -hgroup, -menu, -nav, -output, -ruby, -section, -summary, -time, -mark, -audio, -video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -/* HTML5 display-role reset for older browsers */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section { - display: block; -} - -[class*="col-"] { - float: left; - padding: 15px; - border: 0px; - width: 100%; - margin: 0 auto; -} - -@media only screen and (min-width: 768px) { - .col-1 { - width: 8.33%; - } - - .col-2 { - width: 16.66%; - } - - .col-3 { - width: 25%; - } - - .col-4 { - width: 33.33%; +/* Adapted from: https://stackoverflow.com/questions/20007610/bootstrap-carousel-multiple-frames-at-once, Bootstrap 5 Multi-item Carousel Demo + Date: 13/04/2023*/ +/* Switch to single item display. */ +@media (max-width: 767px) { + .carousel-inner .carousel-item>div { + display: none; } - .col-5 { - width: 41.66%; - } - - .col-6 { - width: 50%; - } - - .col-7 { - width: 58.33%; - } - - .col-8 { - width: 66.66%; + .carousel-inner .carousel-item>div:first-child { + display: block; } +} - .col-9 { - width: 75%; - } +/* Handles moving one item at a time when displaying multiple items. */ +@media (min-width: 768px) { - .col-10 { - width: 83.33%; + .carousel-inner .carousel-item-end.active, + .carousel-inner .carousel-item-next { + transform: translateX(25%); } - .col-11 { - width: 91.66%; + .carousel-inner .carousel-item-start.active, + .carousel-inner .carousel-item-prev { + transform: translateX(-25%); } - - .col-12 { - width: 100%; - } -} - -.content { - /* to stop content being hidden by the fixed footer */ - padding-bottom: 100px; -} - -body { - line-height: 1; -} - -ol, -ul { - list-style: none; -} - -blockquote, -q { - quotes: none; -} - -blockquote:before, -blockquote:after, -q:before, -q:after { - content: ''; - content: none; -} - -/* table { - border-collapse: collapse; - border-spacing: 0; -} */ - - -/* End of resetting */ - - -footer { - background-color: black; - color: white; - position: fixed; - bottom: 0; - left: 0; - width: 100%; -} - - - - -.navbar li a { - color: white; - display: block; - text-align: center; - text-decoration: none; - padding: 14px 16px; -} - -.navbar ul { - list-style-type: none; - margin: 0; - padding: 0; - overflow: hidden; - background-color: black; -} - - -input[type=text] { - float: left; - padding: 6px; - border: none; - margin-top: 8px; - margin-right: 16px; - font-size: 17px; -} - -.navbar li { - float: left; -} - -.navbar li a:hover { - background-color: white; - color: black; -} - -* { - text-align: center; - font-family: sans-serif; -} - -h1 { - color: black; - font-size: 30px; -} - -.error { - text-decoration: none; - color: red; - font-size: 30px; } -li { - list-style-type: none; +/* Get the carousel horizontal */ +.carousel-inner .carousel-item.active, +.carousel-inner .carousel-item-next, +.carousel-inner .carousel-item-prev { + display: flex; } -.loginTable { - margin-left: auto; - margin-right: auto; +/* Moves the entire line smoothly to the left. */ +.carousel-inner .carousel-item-end, +.carousel-inner .carousel-item-start { + transform: translateX(0); } \ No newline at end of file diff --git a/store/templates/_formhelpers.html b/store/templates/_formhelpers.html index f69931b4d697e31a4cb2c94dcabb5b4d5c1e34fc..ed7aeb6002ee0479e2bc5183b925f25c21501cb7 100644 --- a/store/templates/_formhelpers.html +++ b/store/templates/_formhelpers.html @@ -4,14 +4,13 @@ https://flask.palletsprojects.com/en/2.2.x/patterns/wtforms/#forms-in-templates --> {% macro render_field(field) %} -<dt>{{ field.label }} -<dd>{{ field(**kwargs)|safe }} +<div id="{{field.name}}_field" class="mb-3"> + {{ field.label(class="form-label") }} + {{ field(**kwargs)|safe }} {% if field.errors %} - <ul class=errors> - {% for error in field.errors %} - <li>{{ error }}</li> - {% endfor %} - </ul> + {% for error in field.errors %} + <div class="invalid-feedback">{{ error }}</div> + {% endfor %} {% endif %} -</dd> +</div> {% endmacro %} \ No newline at end of file diff --git a/store/templates/base.html b/store/templates/base.html index 078786afef4d5ea9499d4648f8c6d634a52d9310..6a9177e818cf2d5e07eb152970550c4361807dbb 100644 --- a/store/templates/base.html +++ b/store/templates/base.html @@ -3,60 +3,102 @@ <html lang="en"> <head> - <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> + <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{% block title %}{% endblock%}</title> - <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='_main.css') }}"> <!-- Load the CSS. --> + <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" + integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='_main.css') }}"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> </head> -<body> - <header class="header"> - <a href="{{ url_for('index')}}">ANTIQUES ONLINE</a> - </header> +<body class="d-flex flex-column min-vh-100"> + <!-- https://getbootstrap.com/docs/4.0/components/navbar/ --> + <nav class="navbar navbar-expand-lg navbar-dark" style="background-color: black"> + <div class="container-fluid"> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" + aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> - <nav class="navbar"> - <ul class="navbar-list"> - <li><a href="{{ url_for('basket')}}">Basket</a></li> - <li><a href="{{ url_for('items')}}">Items</a></li> - <li><a href="{{ url_for('item_sets')}}">Item Sets</a></li> + <!-- Once in mobile mode we want the home text to be inline with the burger menu. --> + <a href="/" class="text-light text-decoration-none d-block d-lg-none"> + <span class="fs-4">ANTIQUES ONLINE</span> + </a> - {% if current_user.is_authenticated %} - <li><a href="{{ url_for('account')}}">Account</a></li> - <li><a href="{{ url_for('logout')}}">Logout</a></li> - <li><a class="welcome">Welcome, {{ current_user.username }}!</a></li> - {% else %} - <li><a href="{{ url_for('login')}}">Login</a></li> - <li><a href="{{ url_for('register')}}">Register</a></li> - {% endif %} - - <form method="POST" action="{{url_for('search')}}" class="search"> - {{search_form.hidden_tag()}} - {{render_field(search_form.query) }} - {{search_form.submit()}} - </form> - </ul> + <div class="collapse navbar-collapse" id="navbarSupportedContent"> + <div class="container"> + <!-- Use a row for columns to perfectly centre the title. --> + <div class="row"> + <div class="col-lg d-flex justify-content-start text-nowrap"> + <ul class="navbar-nav"> + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('basket')}}">Basket</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('items')}}">Items</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('item_sets')}}">Item Sets</a> + </li> + {% if current_user.is_authenticated %} + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('account')}}">Account</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('logout')}}">Logout</a> + </li> + {% else %} + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('login')}}">Login</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="{{ url_for('register')}}">Register</a> + </li> + {% endif %} + </ul> + </div> + <div class="col-lg d-flex justify-content-center"> + <!-- Just force it into the centre, it's basically already there anyway. --> + <a href="/" class="text-light text-decoration-none d-none d-lg-block" + style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"> + <span class="fs-4">ANTIQUES ONLINE</span> + </a> + </div> + <div class="col-lg d-flex justify-content-end"> + <form method="POST" action="{{url_for('search')}}" class="d-flex"> + {{search_form.hidden_tag()}} + {{ search_form.query(class="form-control mr-sm-2")|safe}} + {% if search_form.query.errors %} + {% for error in search_form.query.errors %} + <div class="invalid-feedback">{{ error }}</div> + {% endfor %} + {% endif %} + {{search_form.submit(class="btn btn-outline-success")}} + </form> + </div> + </div> + </div> + </div> + </div> </nav> - {% with messages = get_flashed_messages() %} - {% if messages %} - <ul class="flashes"> - {% for message in messages %} - <li class="error">{{ message }}</li> - {% endfor %} - </ul> - {% endif %} - {% endwith %} - - {% block content %} + {% block content %} <!-- Where HTML will go when extended. --> + {% endblock %} - {% endblock %} <!-- Where HTML will go when extended. --> - - <footer class="footer"> - <br> - <p>Contact Info: mail@mail.com</p> - <p>Phone Number 0000 000 0000</p> - <br> + <!-- https://getbootstrap.com/docs/5.2/examples/footers/ --> + <!-- mt-auto will handle put the footer at the bottom if the content doesn't fill the viewport. + It requires the body to be d-flex flex-column min-vh-100 --> + <footer class="mt-auto d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top"> + <p class="col-md-4 mb-0 text-muted px-2">© 2023 Antique's Online</p> + <ul class="nav col-md-4 justify-content-end"> + <li class="px-2 text-muted">Email: admin@antiquesonline.com</li> + <li class="px-2 text-muted">|</li> + <li class="px-2 text-muted">Phone Number: 0000 000 0000</li> + </ul> </footer> + <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" + integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" + crossorigin="anonymous"></script> </body> </html> \ No newline at end of file diff --git a/store/templates/basket.html b/store/templates/basket.html index e5ece960fcb7db9fc589507db810482d2e46e009..c926eab9b05d97bac449c6f3d8cbacd7683b6da1 100644 --- a/store/templates/basket.html +++ b/store/templates/basket.html @@ -1,43 +1,11 @@ {% extends "base.html" %} {% block content %} -<h1>Basket</h1> -<style> - table { - border-collapse: collapse; - width: 100%; - } - - th, - td { - text-align: left; - padding: 8px; - border-bottom: 1px solid #ddd; - } - - th { - background-color: #000000; - color: white; - } - - .remove-button { - background-color: #f44336; - color: white; - border: none; - padding: 8px 16px; - text-align: center; - text-decoration: none; - display: inline-block; - font-size: 16px; - margin: 4px 2px; - cursor: pointer; - } -</style> - -{% if items %} -<div> - <table> - <thead> +<div class="container"> + <h1>Basket</h1> + {% if items %} + <table class="table"> + <thead class="text-light" style="background-color: #000000"> <tr> <th>Item description</th> <th>Item price</th> @@ -52,24 +20,26 @@ <td> <form method="POST" action="/remove_item"> <input type="hidden" name="item" value="{{ item['id'] }}"> - <input type="submit" value="Remove"> + <input type="submit" value="Remove" class="btn btn-danger" style="width: 100px"> </form> </td> </tr> {% endfor %} </tbody> - <tfoot> + <tfoot style="background-color: #f2f2f2"> <tr> <td>Total price:</td> <td>£{{ total_price }}</td> - <td></td> + <td> + <a class="btn btn-success" href="{{url_for('checkout', total_price = total_price)}}" + style="width: 100px">Checkout</a> + </td> </tr> </tfoot> </table> - <a href="{{url_for('checkout', total_price = total_price)}}">Checkout</a> + {% else %} + <p>Your basket is empty.</p> + {% endif %} </div> -{% else %} -<p>Your basket is empty.</p> -{% endif %} {% endblock %} \ No newline at end of file diff --git a/store/templates/checkout.html b/store/templates/checkout.html index bbd426d5772a66927fa6d8616c83173b108967c1..7ecd7c30bf1fd77fe0c1a464916c399ebc05ca54 100644 --- a/store/templates/checkout.html +++ b/store/templates/checkout.html @@ -4,111 +4,44 @@ {% block content %} -<style> - h1 { - padding: 15px; - } - - .grid-container-element { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 20px; - width: 90%; - padding: 10px; - } - - .grid-child-element { - margin: 10px; - padding: 10px; - } - - form { - display: flex; - flex-direction: column; - align-items: center; - } - - label { - display: inline-block; - width: 150px; - text-align: left; - margin-right: 10px; - padding: 5px; - } - - input[type="text"], - select { - margin-left: 10px; - outline: none; - padding: 5px; - border: 1px solid gray; - } - - table { - border-collapse: collapse; - width: 100%; - } - - th, - td { - text-align: left; - padding: 8px; - border-bottom: 1px solid #ddd; - } - - th { - background-color: #000000; - color: white; - } -</style> -<div class="grid-container-element"> - <div class="grid-child-element"> - <h1>Checkout</h1> - <form method='POST' class="content"> - {{ form.csrf_token }} - <br /> - <label for="name">{{ form.name.label }}{{ form.name }}</label><br /> - <br /> - <label for="card_number">{{ form.card_number.label }}{{ form.card_number }}</label><br /> - <br /> - <label for="exp_date_month">{{ form.exp_date_month.label }}{{ form.exp_date_month }}</label> - <label for="exp_date_year">{{ form.exp_date_year.label }}{{ form.exp_date_year }}</label><br /> - <br /> - <label for="cvv_2">{{ form.cvv_2.label }}{{ form.cvv_2 }}</label><br /> - <br /> - <label for="address">{{form.address.label}}{{form.address}}</label><br /> - <br /> - <label for="postcode">{{form.postcode.label}}{{form.postcode}}</label><br /> - <br /> - <p><input type="submit" value="Complete payment"></p> - </form> - </div> - <div class="grid-child-element"> - <h1>Order Summary</h1> - <table class="content"> - <thead> - <tr> - <th>Item description</th> - <th>Item price</th> - <th></th> - </tr> - </thead> - <tbody> - {% for item in items %} - <tr> - <td>{{ item['description'] }}</td> - <td>£{{ item['price'] }}</td> - </tr> - {% endfor %} - </tbody> - <tfoot> - <tr> - <td>Total price:</td> - <td>£{{ total_price }}</td> - <td></td> - </tr> - </tfoot> - </table> +<div class="container"> + <div class="row"> + <div class="col"> + <h1>Checkout</h1> + <form method='POST'> + {{ form.csrf_token }} + {{ render_field(form.name, class="form-control") }} + {{ render_field(form.card_number, class="form-control") }} + {{ render_field(form.exp_date_month, class="form-control") }} + {{ render_field(form.exp_date_year, class="form-control") }} + {{ render_field(form.cvv_2, class="form-control") }} + {{ render_field(form.address, class="form-control") }} + {{ render_field(form.postcode, class="form-control") }} + <input class="btn btn-primary" type="submit" value="Complete payment"> + </form> + </div> + <div class="col"> + <h1>Order Summary</h1> + <table class="content"> + <table class="table"> + <thead class="text-light" style="background-color: #000000"> + <tr> + <th>Item description</th> + <th>Item price</th> + <th></th> + </tr> + </thead> + <tbody> + {% for item in items %} + <tr> + <td>{{ item['description'] }}</td> + <td>£{{ item['price'] }}</td> + </tr> + {% endfor %} + </tbody> + </table> + </table> + </div> </div> </div> {% endblock %} \ No newline at end of file diff --git a/store/templates/index.html b/store/templates/index.html index 1dc5e829b93598987aae3a4398435414b28054c9..7efed29089b0b362383d079488a3bddf3383284d 100644 --- a/store/templates/index.html +++ b/store/templates/index.html @@ -1,19 +1,77 @@ {%extends 'base.html' %} - {% block title %} Welcome! {% endblock %} - {% block content %} - <br> - <h1>Welcome to the Official Website of Antiques Online</h1> - <br> - <p>We maintain a large collection of fascinating Antiques and Collectibles to view on our Website.</p> - <p>Click <a href="{{ url_for('items')}}">*HERE*</a> to view some of them.</p> - <p>Hurry, they are very popular!</p> - <br><br> - <p>If you are new here, press <a href="{{ url_for('register')}}">*HERE*</a> to Register for an account</p> - <br> - <p>Returning Customers can Login <a href="{{ url_for('login')}}">*HERE*</a></p> - <br> - +<div class="container"> + <p class="my-2"> + Antique's Online maintains a large collection of antiques and collectables stored in various repositories around + the + world. Our business sells these items through its online store and also through a variety of online auction + houses. + <br> + The below is an example of the collections our partner auction houses hold. + </p> +</div> +<!-- Adapted from: https://stackoverflow.com/questions/20007610/bootstrap-carousel-multiple-frames-at-once, Bootstrap 5 Multi-item Carousel Demo + Date: 13/04/2023 +Really want to completely redo this using card-groups, but for time saving measures this'll do. +--> +{% for repository in repositories %} +<div class="container text-center my-3"> + <!-- Ideally the name of the store should be here. --> + <h2 class="font-weight-light">ALTERNATE STORE {{loop.index}}</h2> + <div class="row mx-auto my-auto justify-content-center"> + <div id="recipeCarousel{{loop.index}}" class="carousel slide" data-bs-ride="carousel"> + <div class="carousel-inner" role="listbox"> + {% for item in repository.items %} + <div class="carousel-item {{'active' if loop.index0 == 0}} justify-content-center"> + <div class="col-md-3"> + <div class="card"> + <div class="card-img"> + <img src="static\image_placeholder.png" class="img-fluid" + style="width: 200px; height: 200px;"> + </div> + <div class="card-body" style="height: 128px;"> + <p class="card-text">{{ item.description}}</p> + <a href="{{url_for('item_page', item_id = item.id)}}" class="btn btn-primary">View + Details</a> + </div> + </div> + </div> + </div> + {% endfor %} + </div> + <!-- Controls for the carousel, href needs to be a unique id matching the carousel name. + This isn't perfect, there's some overlap with the "View" button. + --> + <a class="carousel-control-prev bg-transparent w-aut" href="#recipeCarousel{{loop.index}}" role="button" + data-bs-slide="prev"> + <span class="carousel-control-prev-icon" aria-hidden="true"></span> + </a> + <a class="carousel-control-next bg-transparent w-aut" href="#recipeCarousel{{loop.index}}" role="button" + data-bs-slide="next"> + <span class="carousel-control-next-icon" aria-hidden="true"></span> + </a> + </div> + </div> +</div> +{% endfor %} + +<script> + // Clone the slides into divs. + let items = document.querySelectorAll('.carousel .carousel-item') -{% endblock %} + items.forEach((el) => { + const minPerSlide = 4 + let next = el.nextElementSibling + for (var i = 1; i < minPerSlide; i++) { + if (!next) { + // wrap carousel by using first child + next = items[0] + } + let cloneChild = next.cloneNode(true) + el.appendChild(cloneChild.children[0]) + next = next.nextElementSibling + } + }) +</script> +{% endblock %} \ No newline at end of file diff --git a/store/templates/item_page.html b/store/templates/item_page.html index 3f4434c44257d019a7b5c24a018913cdd65df523..f64a9968cf1fd774632329d3bbde3307961c5bfa 100644 --- a/store/templates/item_page.html +++ b/store/templates/item_page.html @@ -1,18 +1,44 @@ {%extends 'base.html' %} - -{% block content %} {% block title %} Item Page | Antiques Online {% endblock %} -<div> - <img src='..\static\image_placeholder.png' alt="Image Placeholder" width="200" height="170"> - <br /> - Item price: £{{item_price}} - <br /> - Item description: {{item_description}} - <br /> - <form method="POST" action="{{url_for ('add_to_basket') }}"> - <input type="hidden" name="item_id" value="{{ item_id }}"> - <input class="button" type="submit" value="Add to basket"> - </form> -</div> +{% block content %} +<div class="container vertical-center"> + <div class="row"> + <div class="col text-center"> + <div class="align-items-center"> + <img class="align-self-center" src="static\image_placeholder.png" alt="{{ item.description }}" + style="width: 200px; height: 200px;"> <!-- Set image size to ensure content is always fitting. --> + <h2>{{ item.description }}</h2> + <p>£{{ item.price }}</p> + <form method="POST" + action="{{ url_for('add_to_basket_set') if item.items else url_for('add_to_basket') }}"> + <input type="hidden" name="item_id" value="{{ item.id }}"> + <input class="btn btn-success" type="submit" value="Add to basket"> + </form> + </div> + </div> + </div> + <div class="row text-center"> + {% if item.items %} + <h1>Items contained in set: </h1> + <table class="table"> + <thead> + <tr> + <th>Item description</th> + <th>Item price</th> + <th></th> + </tr> + </thead> + <tbody> + {% for item in item.items %} + <tr> + <td>{{ item['description'] }}</td> + <td>£{{ item['price'] }}</td> + </tr> + {% endfor %} + </tbody> + </table> + {% endif %} + </div> +</div> {% endblock %} \ No newline at end of file diff --git a/store/templates/item_set_page.html b/store/templates/item_set_page.html deleted file mode 100644 index d2b0b0136412c49e5838ce3d769bfe1306b28aee..0000000000000000000000000000000000000000 --- a/store/templates/item_set_page.html +++ /dev/null @@ -1,56 +0,0 @@ -{%extends 'base.html' %} - -{% block content %} -{% block title %} Item Set Page | Antiques Online {% endblock %} -<style> - table { - margin-left: auto; - margin-right: auto; - font: inherit; - } - - h1 { - font-size: 25px; - font: inherit; - font-weight: bold; - } -</style> -<div> - <img src='..\static\image_placeholder.png' alt="Image Placeholder" width="200" height="170"> - <br> - Item price: £{{item_price}} - <br> - Item description: {{item_description}} - <br> - <form method="POST" action="{{url_for ('add_to_basket_set') }}"> - <input type="hidden" name="item_id" value="{{ item_id }}"> - <input class="button" type="submit" value="Add to basket"> - </form> - <br> -</div> -<div> - {% if contained_items %} - <h1>Items contained in set: </h1> - <table> - <thead> - <tr> - <th>Item description</th> - <th>Item price</th> - <th></th> - </tr> - </thead> - <tbody> - {% for item in contained_items %} - <tr> - <td>{{ item['description'] }}</td> - <td>£{{ item['price'] }}</td> - </tr> - {% endfor %} - </tbody> - </table> - {% else %} - <p>Item set is empty.</p> - {% endif %} -</div> - -{% endblock %} \ No newline at end of file diff --git a/store/templates/item_sets.html b/store/templates/item_sets.html deleted file mode 100644 index 09e104dfee390ce96836849139ede00890cf913c..0000000000000000000000000000000000000000 --- a/store/templates/item_sets.html +++ /dev/null @@ -1,56 +0,0 @@ -{%extends 'base.html' %} - -{% block title %} Item Sets | Antiques Online {% endblock %} - -{% block content %} - -<style> - .grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - grid-gap: 10px; - grid-auto-rows: minmax(100px, auto); - padding-bottom: 100px; - } - - .grid-item { - grid-row: span 1; - grid-column: span 1; - padding: 10px; - } - - .grid-item img { - max-width: 100%; - height: auto; - } - - .grid-item h2 { - margin: 10px 0; - font-size: 18px; - - } - - .grid-item p { - margin: 5px 0; - font-size: 14px; - } -</style> - -<div class="grid"> - {% if items %} - {% for item in items %} - <div class="grid-item"> - - <img src="static\image_placeholder.png" alt="{{ item.description }}"> - <h2>{{ item.description }}</h2> - <p>£{{ item.price }}</p> - <a href="{{url_for('item_set_page', item_id = item.id)}}">View - Details</a> - - </div> - {% endfor %} - {% else %} - <p>No items available</p> - {% endif %} -</div> -{% endblock %} \ No newline at end of file diff --git a/store/templates/items.html b/store/templates/items.html index 6704ee9b0177ca1d60220acfa67ae23ea418b3a3..c67c840de60d104f7506362f59c88fa6405eecfb 100644 --- a/store/templates/items.html +++ b/store/templates/items.html @@ -1,56 +1,29 @@ {%extends 'base.html' %} - - - -{% block content %} {% block title %} Items | Antiques Online {% endblock %} -<style> - .grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - grid-gap: 10px; - grid-auto-rows: minmax(100px, auto); - padding-bottom: 100px; - } - - .grid-item { - grid-row: span 1; - grid-column: span 1; - padding: 10px; - } - - .grid-item img { - max-width: 100%; - height: auto; - } - - .grid-item h2 { - margin: 10px 0; - font-size: 18px; - - } - - .grid-item p { - margin: 5px 0; - font-size: 14px; - } -</style> - -<div class="grid"> - {% if items %} - {% for item in items %} - <div class="grid-item"> - - <img src="static\image_placeholder.png" alt="{{ item.description }}"> - <h2>{{ item.description }}</h2> - <p>£{{ item.price }}</p> - <a href="{{url_for('item_page', item_id = item.id)}}">View - Details</a> - +{% block content %} +<!-- https://getbootstrap.com/docs/4.0/layout/grid/ --> +<div class="container pb-3"> + <div class="row"> + {% if items %} + {% for item in items %} + <div class="col text-center"> + <div class="align-items-center"> + <img class="align-self-center" src="static\image_placeholder.png" alt="{{ item.description }}" + style="width: 200px; height: 200px;"> <!-- Set image size to ensure content is always fitting. --> + <h2>{{ item.description }}</h2> + <p>£{{ item.price }}</p> + <!-- Ternary operator to genericise the page to sets and items. Because of python shenanigans trying + to access an attribute that doesn't actually exist doesn't neccesarily cause an immediate exception and + so this can be used to check if the object is an item or item set.--> + <a class="btn btn-primary" + href="{{url_for('item_set_page', item_id = item.id) if item.items else url_for('item_page', item_id = item.id)}}">View + Details</a> + </div> + </div> + {% endfor %} + {% else %} + <p>No items available</p> + {% endif %} </div> - {% endfor %} - {% else %} - <p>No items available</p> - {% endif %} </div> {% endblock %} \ No newline at end of file diff --git a/store/templates/search.html b/store/templates/search.html deleted file mode 100644 index d14da500827b637a974b5028863f9c92c05d9bf3..0000000000000000000000000000000000000000 --- a/store/templates/search.html +++ /dev/null @@ -1,53 +0,0 @@ -{%extends 'base.html' %} -{% block title %} Search | Antiques Online {% endblock %} -{% block content %} -Searching for {{form.query.data}} -<style> - .grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - grid-gap: 10px; - grid-auto-rows: minmax(100px, auto); - } - - .grid-item { - grid-row: span 1; - grid-column: span 1; - padding: 10px; - } - - .grid-item img { - max-width: 100%; - height: auto; - } - - .grid-item h2 { - margin: 10px 0; - font-size: 18px; - - } - - .grid-item p { - margin: 5px 0; - font-size: 14px; - } -</style> - -<div class="grid"> - {% if items %} - {% for item in items %} - <div class="grid-item"> - - <img src="static\image_placeholder.png" alt="{{ item.description }}"> - <h2>{{ item.description }}</h2> - <p>£{{ item.price }}</p> - <a href="{{url_for('item_page', item_id = item.id)}}">View - Details</a> - - </div> - {% endfor %} - {% else %} - <p>No items available</p> - {% endif %} -</div> -{% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/ChangePhNumber.html b/store/templates/userContent/ChangePhNumber.html index 76ec481786f40b2e0feaa19de551ad806f5e7389..b1790d5ad0f4ef1decab231f63ba1d239ef8b22a 100644 --- a/store/templates/userContent/ChangePhNumber.html +++ b/store/templates/userContent/ChangePhNumber.html @@ -8,7 +8,6 @@ <label for="password"><b>Password verification</b></label> <input type="password" placeholder="Enter Password" name="password" id="password" required> - <label for="NewNumber"><b> Enter New Number</b></label> <input type="NewNumber" placeholder="Enter new Number" name="NewNumber" id="NewNumber" required> diff --git a/store/templates/userContent/ChangeUsername.html b/store/templates/userContent/ChangeUsername.html index 155155bb76accf9fbcc413266f64ac21d79ea792..f4bdcc1e399872c89c074b772b822e7abbadca9b 100644 --- a/store/templates/userContent/ChangeUsername.html +++ b/store/templates/userContent/ChangeUsername.html @@ -8,8 +8,6 @@ <label for="password"><b>Password verification</b></label> <input type="password" placeholder="Enter Password" name="password" id="password" required> - - <label for="NewUsername"><b>New username</b></label> <input type="NewUsername" placeholder="Enter new Username" name="NewUsername" id="NewUsername" required> diff --git a/store/templates/userContent/account.html b/store/templates/userContent/account.html deleted file mode 100644 index b97dd74b67fc08c52978d95a9b399f38fe9eabbe..0000000000000000000000000000000000000000 --- a/store/templates/userContent/account.html +++ /dev/null @@ -1,12 +0,0 @@ -{%extends 'base.html' %} - -{% block content %} -{% block title %} Account{% endblock %} -<h1>account Information</h1> -<ul> - <li><a href="{{ url_for('accountDetails', user_id=current_user.id)}}">View my Account details</a></li> - <li><a href="{{ url_for('orders', user_id=current_user.id)}}">View Orders</a></li> - <li><a href="{{ url_for('addresses', user_id=current_user.id)}}">View shipping address</a></li> - <li><a href="{{ url_for('Payment', user_id=current_user.id)}}">View your payment method</a></li> -</ul> -{% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/accountDetails.html b/store/templates/userContent/accountDetails.html deleted file mode 100644 index b1645cb90da97e758bc3a200eb0eabf695d8df49..0000000000000000000000000000000000000000 --- a/store/templates/userContent/accountDetails.html +++ /dev/null @@ -1,34 +0,0 @@ -{%extends 'base.html' %} - -{% block content %} -<h1>Account Details</h1> -<h1>Welcome, {{ user.username }}</h1> -<table style="width:100%"> - <tr> - <th>Your username is:</th> - <th>{{ user.username }}</th> - <th><a href="{{ url_for('ChangeUsername')}}">change your username</a></th> - - </tr> - <tr> - <td>Your email address is:</td> - <td>{{ user.email }}</td> - <td><a href="{{ url_for('ChangeEmail')}}">Change email address</a></td> - </tr> - <tr> - <th>Your Phone Number is:</th> - <td>{{ user.phone_number }}</td> - <td><a href="{{ url_for('ChangePhNumber')}}">change phone number</a></td> - </tr> -</table> -{% endblock %} - -<!-- - {% block title %} Account{% endblock %} - <h1>Account Details</h1> - <h1>Welcome, {{ user.username }}</h1> - <p>Your email address is: {{ user.email }}</p> - <p>Your Phone Number is: {{ user.phone_number }}</p> - - - --> \ No newline at end of file diff --git a/store/templates/userContent/admin.html b/store/templates/userContent/admin.html deleted file mode 100644 index 35187f877c03846f0c9a72b16db649f42845f9aa..0000000000000000000000000000000000000000 --- a/store/templates/userContent/admin.html +++ /dev/null @@ -1,13 +0,0 @@ -{%extends 'base.html' %} - -{% block content %} -{% block title %} Account{% endblock %} -<h1>Admin usertype account Information</h1> -<ul> - <li><a href="{{ url_for('accountDetails')}}">View my Account details</a></li> - <li><a href="{{ url_for('view_address')}}">View my shipping address</a></li> - <li><a href="{{ url_for('database_management')}}">Edit existing entries</a></li> - <li><a href="{{ url_for('database_management_add')}}">Add new entries</a></li> - -</ul> -{% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/database_management.html b/store/templates/userContent/database_management.html index 1c731139628312a3db62625d6754993fa3eba1ab..3b8673566ff0cebb7c2b9fd0719dfa0e62c393c9 100644 --- a/store/templates/userContent/database_management.html +++ b/store/templates/userContent/database_management.html @@ -2,66 +2,63 @@ {%extends 'base.html' %} {% block title %} Database Management | Antiques Online {% endblock %} {% block content %} -<form method="POST"> - {{access_data_form.hidden_tag()}} - <dl> - <table> - <tr> - <td>{{ render_field(access_data_form.table) }} </td> - </tr> - <tr> - <td>{{ render_field(access_data_form.id) }} </td> - </tr> - </table> - </dl> - <br> - {{access_data_form.submit()}} - <br> -</form> - -{% if main_item %} -<div> - <img src='..\static\image_placeholder.png' alt="Image Placeholder" width="200" height="170"> - <br /> - Item price: £{{main_item.price}} - <br /> - Item description: {{main_item.description}} - <br /> - {% if is_item %} - <button onclick="deleteItem({{main_item.id}})">Delete</button> - {%else%} - <button onclick="deleteItemSet({{main_item.id}})">Delete</button> - {% endif %} - - {% if not is_item %} +<div class="container my-2 d-flex align-items-center justify-content-center"> <div> - <h1>Items contained in set: </h1> - <table> - <thead> - <tr> - <th>Item description</th> - <th>Item price</th> - <th></th> - </tr> - </thead> - <tbody> - {% for item in main_item.items %} - <tr> - <td>{{ item['description'] }}</td> - <td>£{{ item['price'] }}</td> - <button onclick="deleteItemFromSet({{item.id}}, {{main_item.id}})">Delete</button> - </tr> - {% endfor %} - </tbody> - </table> - <label for="itemID">Item ID:</label><br> - <input type="number" id="itemID" name="itemID"><br> - <button onclick="addItemToSet({{main_item.id}})">Add</button> + <form method="POST"> + {{access_data_form.hidden_tag()}} + {{ render_field(access_data_form.table, class="form-control") }} + {{ render_field(access_data_form.id, class="form-control") }} + {{access_data_form.submit(class="btn btn-primary")}} + </form> + <hr> + {% if main_item %} + <div class="text-center"> + <img src='..\static\image_placeholder.png' alt="Image Placeholder" width="200" height="200"> + <br /> + Item price: £{{main_item.price}} + <br /> + Item description: {{main_item.description}} + <br /> + {% if is_item %} + <button class="btn btn-danger mt-2" onclick="deleteItem({{main_item.id}})">Delete</button> + {%else%} + <button class="btn btn-danger mt-2" onclick="deleteItemSet({{main_item.id}})">Delete</button> + {% endif %} + {% if not is_item %} + <hr> + <div class="text-center"> + <h1>Items contained in set: </h1> + <table class="table"> + <thead> + <tr> + <th>Item description</th> + <th>Item price</th> + <th></th> + </tr> + </thead> + <tbody> + {% for item in main_item.items %} + <tr> + <td>{{ item['description'] }}</td> + <td>£{{ item['price'] }}</td> + <td><button class="btn btn-danger" + onclick="deleteItemFromSet({{item.id}}, {{main_item.id}})">Delete</button></td> + </tr> + {% endfor %} + </tbody> + <tfoot clas style="background-color: #f2f2f2"> + <td><label class="form-label" for="itemID">Item ID</label></td> + <td><input class="form-control" type="number" id="itemID" name="itemID"></td> + <td><button class="btn btn-primary" onclick="addItemToSet({{main_item.id}})">Add</button> + </td> + </tfoot> + </table> + </div> + {% endif %} + </div> + {% endif %} </div> - {% endif %} </div> -{% endif %} - <script> function addItemToSet(set_id) { console.log(set_id); diff --git a/store/templates/userContent/database_management_add.html b/store/templates/userContent/database_management_add.html index 1ebfc8a0ad44f8cd446ef927f15ab0358f889916..241ad0d335dc8d8847f3fdf5be20b98119582d15 100644 --- a/store/templates/userContent/database_management_add.html +++ b/store/templates/userContent/database_management_add.html @@ -2,33 +2,20 @@ {%extends 'base.html' %} {% block title %} Database Management | Antiques Online {% endblock %} {% block content %} -<form method="POST"> - {{form.hidden_tag()}} - <dl> - <table> - <tr> - <td>{{ render_field(form.table) }} </td> - </tr> - <tr> - <td>{{ render_field(form.description) }} </td> - </tr> - <tr id="price_optional"> - <td>{{ render_field(form.price) }} </td> - </tr> - </div> - </table> - </dl> - <br> - {{form.submit()}} - <br> -</form> - +<div class="container d-flex align-items-center justify-content-center my-2"> + <form method="POST"> + {{form.hidden_tag()}} + {{ render_field(form.table, class="form-control") }} + {{ render_field(form.description, class="form-control") }} + {{ render_field(form.price, class="form-control") }} + {{form.submit(class="btn btn-primary")}} + </form> +</div> <script> $(document).ready(function () { $('#table').change(function () { - $('#price_optional').toggle(); + $('#price_field').toggle(); }); }); </script> - {% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/login.html b/store/templates/userContent/login.html index a225e95501c51033e966a47a6168cc3d0194e090..14feb976c09a491a3343162906f9e0f7a46c23ff 100644 --- a/store/templates/userContent/login.html +++ b/store/templates/userContent/login.html @@ -2,26 +2,15 @@ {%extends 'base.html' %} {% block title %} Login | Antiques Online {% endblock %} {% block content %} -<br> -<h1>Login</h1> -<br> -<div class="container"> - <form method="POST"> - {{form.hidden_tag()}} - <dl> - <table class="loginTable"> - <tr> - <td>{{ render_field(form.username) }} </td> - </tr> - <td>{{ render_field(form.password) }}</td> - </tr> - </table> - </dl> - <br> - {{form.submit()}} - <br> - </form> - <td><a href="{{ url_for('reset_password')}}">I Forgot my Password!</a></td><br><br> - <br> +<div class="container d-flex align-items-center justify-content-center"> + <div class="my-4 w-25"> + <h1>Login</h1> + <form method="POST"> + {{form.hidden_tag()}} + {{ render_field(form.username, class="form-control") }} + {{ render_field(form.password, class="form-control") }} + {{form.submit(class="btn btn-primary")}} + </form> + </div> </div> {% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/register.html b/store/templates/userContent/register.html index d6e4fd49155ca145dbb57149ec98e2c8074eaf2e..2a3d96e08dbab032d1672d31719240d009440ac4 100644 --- a/store/templates/userContent/register.html +++ b/store/templates/userContent/register.html @@ -2,36 +2,19 @@ {%extends 'base.html' %} {% block title %} Register | Antiques Online {% endblock %} {% block content %} -<br> -<h1>Register</h1> -<br> -<div class="container"> - <form method="POST"> - {{form.hidden_tag()}} - <dl> - <table class="loginTable"> - <tr> - <td>{{ render_field(form.username) }} </td> - </tr> - <tr> - <td>{{ render_field(form.email) }} </td> - </tr> - <tr> - <td>{{ render_field(form.phone_number) }}</td> - </tr> - <tr> - <td>{{ render_field(form.password) }}</td> - </tr> - <tr> - <td>{{ render_field(form.confirm) }}</td> - </tr> - </table> - </dl> - <br> - {{ render_field(form.accept_tos) }}<br> - {{form.submit()}} - <br> - </form> - <br> +<div class="container d-flex align-items-center justify-content-center"> + <div class="my-4 w-25"> + <h1>Register</h1> + <form method="POST"> + {{form.hidden_tag()}} + {{ render_field(form.username, class="form-control") }} + {{ render_field(form.email, class="form-control") }} + {{ render_field(form.phone_number, class="form-control") }} + {{ render_field(form.password, class="form-control") }} + {{ render_field(form.confirm, class="form-control") }} + {{ render_field(form.accept_tos, class="form-check-input") }} + {{form.submit(class="btn btn-primary")}} + </form> + </div> </div> {% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/user.html b/store/templates/userContent/user.html index eb4a4c7d2de7c1339c6df657806125dd1e3a672c..0ac2d7f886a4e28469200df75edb5f263ec739a2 100644 --- a/store/templates/userContent/user.html +++ b/store/templates/userContent/user.html @@ -1,10 +1,32 @@ {%extends 'base.html' %} -{% block content %} {% block title %} Account{% endblock %} -<h1>Standard usertype account Information</h1> -<ul> - <li><a href="{{ url_for('accountDetails', user_id=current_user.id)}}">View my Account details</a></li> - <li><a href="{{ url_for('addAdress', user_id=current_user.id)}}">Add shipping address</a></li> - <li><a href="{{ url_for('view_address', user_id=current_user.id)}}">View your shipping address</a></li> -</ul> +{% block content %} +<div class="container text-center"> + <h1>Account Information</h1> + <div class="p-1"> + Username: {{ user.username }} + <a class="btn btn-primary" href="{{ url_for('ChangeUsername')}}">Change your username</a> + </div> + <div class="p-1"> + Email: {{ user.email }} + <a class="btn btn-primary" href="{{ url_for('ChangeEmail')}}">Change email address</a> + </div> + <div class="p-1"> + Phone Number: {{ user.phone_number }} + <a class="btn btn-primary" href="{{ url_for('ChangePhNumber')}}">Change phone number</a> + </div> + {% if userType == "standard" %} + <div class="p-1"> + <a class="mx-auto btn btn-primary" href="{{ url_for('addAdress', user_id=current_user.id)}}">Add shipping + address</a> + <a class="mx-auto btn btn-primary" href="{{ url_for('view_address', user_id=current_user.id)}}">View shipping + address</a> + </div> + {% else %} + <div class="p-1"> + <a class="mx-auto btn btn-primary" href="{{ url_for('database_management')}}">Edit database entries</a> + <a class="mx-auto btn btn-primary" href="{{ url_for('database_management_add')}}">Add database entries</a> + </div> + {% endif %} +</div> {% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/verify_code_security1.html b/store/templates/userContent/verify_code_security1.html deleted file mode 100644 index c54d763fadff499f70aec951d63044cf4536d79b..0000000000000000000000000000000000000000 --- a/store/templates/userContent/verify_code_security1.html +++ /dev/null @@ -1,15 +0,0 @@ -{%extends 'base.html' %} -{% block content %} -{% block title %} Verify reset Password {% endblock %} -<form method="POST" action="{{ url_for('verify_code_security1') }}" style="float: center; text-align: center;"> - <div class="container"> - <h1>Reset security answer</h1> - - <label for="verification_code"><b>Enter your code </b></label> - <input type="verification_code" placeholder="Enter your code " name="verification_code" id="verification_code" - required> - - <input class="button" type="submit" value="Reset security answer"> - </div> -</form> -{% endblock %} \ No newline at end of file diff --git a/store/templates/userContent/verify_code_security1_confirm.html b/store/templates/userContent/verify_code_security1_confirm.html deleted file mode 100644 index c3f5889fbbf3b5b3a90e2705f7a9651c4d19252a..0000000000000000000000000000000000000000 --- a/store/templates/userContent/verify_code_security1_confirm.html +++ /dev/null @@ -1,20 +0,0 @@ -{%extends 'base.html' %} -{% block content %} -{% block title %} Verify reset Password {% endblock %} -<form method="POST" action="{{ url_for('verify_code_security1_confirm') }}" style="float: center; text-align: center;"> - <div class="container"> - <h1>Reset security question</h1> - - - <label for="securityQ1"><b>what is your favourite colour</b></label> - <input type="securityQ1" placeholder="Enter a colour" name="securityQ1" id="securityQ1" required> - - - <label for="confirm_securityQ1"><b>confirm answer</b></label> - <input type="confirm_securityQ1" placeholder="confirm answer" name="confirm_securityQ1" id="confirm_securityQ1" - required> - - <input class="button" type="submit" value="confirm password"> - </div> -</form> -{% endblock %} \ No newline at end of file diff --git a/store/utility.py b/store/utility.py index 2b20c98af45a59f108e043de05f828408f4523b6..90e607377f02fb83c15696741c2ffb207ecfcc2c 100644 --- a/store/utility.py +++ b/store/utility.py @@ -7,6 +7,7 @@ from sqlalchemy import select, func import datetime from store import * import re +import requests # Difference between filter and filter_by: https://stackoverflow.com/a/31560897 @@ -89,6 +90,13 @@ def get_by_keyword(substring): ).all() return item_sets + items + items = Item.query.filter(func.lower(Item.description.contains(substring))).all() + items = [item for item in items if item.date_sold == None] + item_sets = ItemSet.query.filter( + func.lower(ItemSet.description.contains(substring)) + ).all() + + return item_sets + items def get_itemsets_by_item_id(item_id): @@ -130,9 +138,7 @@ def remove_item_set(item): def sell_item_set(item_set, date=datetime.datetime.today()): for item in item_set.items: - print(item) item.date_sold = date - print(item) db.session.commit() remove_item_set(item_set)