Link to the deployed wesite heroku
Link to the GitHub repository github
Create a build a full-stack site for Build-A-Buffet, providing an authentication mechanism and paid access to facilitate the purchase of a product/service. Build-A-Buffet is a mail order catering service that creates buffet meals for: Wedding, Parties, Functions and Corporate Events. They provide a selection of menus at varying price points to suit the expectations of each event. There will also be the ability to have a menu built for the Customer; by input a range of criteria and having the site build the menu to suit the criteria (e.g. No. of guests, dietary requirements etc.)
The app should be designed ‘mobile first’, and should be equally as accessible through desktop and laptop devices. Navigation should be intuitive and errors handled gracefully.
- … want to understand what Build-A-Buffet do; visually and quickly, without having to navigate through lots of information.
- … want to be able to browse the different products and services.
- … want to be able to create a bespoke menu by selecting from all produce.
- … want to be able to have a menu suggested to me, based on my requirements.
- … want to be able to choose from different dietary requirements (e.g. vegetarion, vegan)
- … want to be aware of any allergy advice for each product.
- … want to be able to see the price of each product and the total price of my basket at any point.
- … want to be able to see the price per person where it is applicable.
- … want to be able to make online purchases of products and services.
- … want to be able to arrange delivery to a location in the UK of my choosing.
- … want to be able to create a user page, where my personal information and order history is stored.
- … want the site to be secure and my personal and payment information kept safe.
- … to be able to maintain a list of products.
- … to be able to track orders.
- … to be able to track payments and webhooks
I designed the site around the following templates:
index.html - to introduce the user to the company and provide navigation to the other areas of the site.
allergies.html - to understand how different dietary and allergy requirements are accomodated.
products.html - to list all the products based on the user's menu selection.
search_products.html - to return all the products based on the user's search parameters.
product_detail.html - to provide more detail on each product including servings and options (where applicable).
basket.html - to view all the products currently in the basket.
edit_product.html - to edit the products currently in the basket.
checkout.html - a secure checkout where registered and guest users can make purchases.
order_success.html - to show an order has been processed succesfully and to show previous orders.
bartholemew.html - to assist the Customer in building an appropriate buffet, based on thier requirements.
bartholemew_output.html - to display to the the Customer Bartholemew's suggested buffet (along with cost information).
profile.html - to allow the Customer to store and update personal information and view order history.
service.html - to contact the Site-Owner through a question form.
For the Site-Owner ...
product_admin.html - to modify/delete: product, option or category.
add_product.html - to add: product, option or category.
Allauth libraries were used for sign up, log in and email validation
I produced the following mockups prior to writing any code. I had sourced the 'Grayscale' template from start bootstrap and stock images from pexels.com. I used this theme and these images in the mockups.
The core scheme of the app is the 'Grayscale' theme from start bootstrap
The main colour scheme is based on the 'GET STARTED' button on 'Grayscale'. I used variations of this colour to give a 'brand' to the site.
- #303F3F for main text
- #71B7B2 for mouseover text
- #426765 for buttons and secondary text
The main fonts used in 'Grayscale' are:
- font-family: 'Nunito'
- font-family: 'Varela Round'
I used these fonts exclusively.
The approach I took for designing the site, was to start with the small media device, portrait view, design that, then make any adaptations for a tablet, portrait view, and finally any changes for a large size, landscape view.. I constructed the code in the mobile-first, portrait view, then added specific media queries for portrait and lanscape views. I again used code from stackoverflow.com to enable this. Finally, I added bespoke media queries for screen sizes. I also set font sizes to be responsive, utilising some code from css-tricks and made by Mike
font-size: calc([minimum size] + ([maximum size] - [minimum size]) * ((100vw - [minimum viewport width]) / ([maximum viewport width] - [minimum viewport width])));
This code, along with using vw and vh for font sizes and certain features, such as banners and images, allowed the site to be almost fully responsive across different portrait view sizes.
... to understand what Build-A-Buffet do; visually and quickly, without having to navigate
- Navigation Menu at top of screen
- Link to bartholemew.html to assist the Customer in getting started
- A Search Bar at top of screen
- View of current basket
- Information on food
- A link to allergies.html for dietary info
- Contact info at foot of screen
... to be able to browse the different products and services.
- Menu list of products
- Ability to search products
... to be able to create a bespoke menu by selecting from all produce.
- Add products to Basket
- Edit products in Basket
- Delete products from Basket
... to be able to have a menu suggested to me, based on my requirements.
- Input requirements and output menu based on requirements
... to be able to choose from different dietary requirements (e.g. vegetarion, vegan)
- Dietary requirements captured
- Dietery information presented
... to be aware of any allergy advice for each product.
- Allergy requirements captured
- Allergy information presented
... to be able to see the price of each product and the total price of my basket at any point.
- Price per product is presented in the Basket
- Total price is presented in the Basket
... to be able to see the price per person where it is applicable.
- Price per person displayed only where number # of guests has been captured
... to be able to make online purchases of products and services.
- Full (test) payment service available
... to be able to arrange delivery to a location in the UK of my choosing.
- Delivery details captured
... to be able to create a user page, where my personal information and order history is stored.
- Personal user page available
- Previous orders can be viewed
... the site to be secure and my personal and payment information kept safe.
- Secure user info
- Secure payment info
... to be able to maintain a list of products.
- Ability to administer products
- Update or delete products
- Add products
... to be able to track orders.
- Track orders in Admin view
... to be able to track payments and webhooks.
- Track payments through Stripe
- Create Webhook orders that can be identified if used disconnects mid process
- Track Webhooks through Stripe
It would be cool to go further with Bartholemew and investigate AI and natural language.
The schema for the relational tables can be found in schema
- html - to create the structure and text of each page.
- css - to style each page centrally and individually.
- javascript - was used to power the Bootstrap functionality.
- jquery - was used to power the Bootstrap functionality.
- Python - for interactions between the app, the MongoDB database and the Azure cloud storage.
- Bootstrap plugins - Responsive grid and prebuilt components to enable more responsive design; particularly “accordion” and “toggle” collapsed (hidden) content.
- Font Awesome - for icons.
- Figma - to produce the mockups.
- w3 validator - for html validation.
- jigsaw - for css validation.
- pep8online - for Python validation.
- Heroku - for the back end database.
- Amazon Web Services - for cloud storage to host the uploaded images.
- Django - to provide a web framework.
A Testing Matrix is in testing
This is constructed around the different User Stories and Features; tested against a number of devices and browsers. The findings of the testing are as follows:
There was an error in the console relating to the Bootstrap navbar element. The original js code is...
// Collapse Navbar
var navbarCollapse = function () {
if ($("#mainNav").offset().top > 100) {
$("#mainNav").addClass("navbar-shrink");
} else {
$("#mainNav").removeClass("navbar-shrink");
}
};
// Collapse now if page is not at top
navbarCollapse();
// Collapse the navbar when page is scrolled
$(window).scroll(navbarCollapse);
I altered it to the following to only run when mainNav was not null ...
var navBarEl = document.getElementById('mainNav');
if (navBarEl !== null) {
// Collapse Navbar
var navbarCollapse = function () {
if ($("#mainNav").offset().top > 100) {
$("#mainNav").addClass("navbar-shrink");
} else {
$("#mainNav").removeClass("navbar-shrink");
}
};
// Collapse now if page is not at top
navbarCollapse();
// Collapse the navbar when page is scrolled
$(window).scroll(navbarCollapse);
}
2 error were found when testing this User Story:
- A typo on bartholemew_output.html that stated "This total cost of this buffet is £100.50.". This was corrected to "The total cost of this buffet is £100.50.".
- The total cost of the buffet as described by Barthgolemew does not match Basket total. This was due to a double-count in the bartholemew view when there was already an existing, identical item in the basket. I altered the code to include a new variable price_per_person which removed this double count.
There was an issue with the complete order button not functioning on checkout.html on the Microsoft Edge browser, but this was down to a previous version of the validation.js file (there was an invalid charachter in the phone number text box) cache-ing in the browser. Resetting the browser corrected this.
Automatic testing was used occasionally throughout the app, predominantly for testing validation rules, and splitting POST/GET variables.
To run automatic testing, enter into command line:
"python3 manage.py test" for all tests, or
"python3 manage.py test checkout" for specific tests (checkout as an example)
There was 1 particular bug that requred a solution.
- The first was where items (Options, Products etc.) were duplicating. I needed to filter further on product.category matching basket.category. This wasn't working as expected, but with a little bit of research; I discovered the function of Slugify. This solved the problem as it converted the variable to the correct format to compare.
{% if product.name == basket.name and product.category == basket.category %}
altered to
{% if product.name == basket.name and product.category|slugify == basket.category|slugify %}
Screenshots that address the different User Stories.
Screenshots from w3 validator are in the folder validation/html. All of the residual 'errors' in the html code are acceptable to me as they don't take into account Django template code.
- add_product.html-validation
- allergies.html-validation
- bartholemew_output.html-validation
- bartholemew.html-validation
- basket.html-validation
- checkout.html-validation
- edit_product.html-validation
- index.html-validation
- order_success.html-validation
- product_admin.html-validation
- product_detail.html-validation
- products.html-validation
- profile.html-validation
- search_products.html-validation
- service.html-validation
Screenshots from jigsaw are in the folder validation/css
- styles.css-validation was uploaded with the start bootstrap theme. There are some residual errors in this off-the-shelf code.
- slider.css-validation
- checkout.css-validation
- bartholemew.css-validation
Screenshots from pep8online are in the folder validation/python
- bartholemew-python-validation
- basket-python-validation
- checkout-python-validation. 1 warning.
- home-python-validation
- products-python-validation
- profiles-python-validation
- service-python-validation
I deployed to Heroku by the following steps:
- Create a new Heroku app.
- Click on "Reveal Config Vars" to add any hidden environment variables.
- Add the key of "SECRET_KEY" and the value of "...App secret key...", and click on Add, to set the secret key.
- Add the key of "DATABASE_URL" and the value of "...Postgres database...", and click on Add, to utilise Heroku's database.
- Add the key of "USE_AWS" and the value of "true", then click Add, to connect to Amazon web Services.
- Add the key of "AWS_S3_REGION_NAME" and the value of "eu-west-2", then click Add, to connect to Amazon web Services.
- Add the key of "AWS_ACCESS_KEY_ID" and the value of "...AWS access key...", then click Add, to connect to Amazon web Services.
- Add the key of "AWS_SECRET_ACCESS_KEY" and the value of "...AWS secret key...", then click Add, to connect to Amazon web Services.
- Add the key of "STRIPE_PUBLIC_KEY" and the value of "...Stripe public key...", then click Add, to access Stripe secure payments.
- Add the key of "STRIPE_SECRET_KEY" and the value of "...Stripe secret key...", then click Add, to access Stripe secure payments.
- Add the key of "STRIPE_WH_SECRET" and the value of "...Stripe webhook key...", then click Add, to access Stripe Webhooks.
- Add the key of "EMAIL_HOST_USER" and the value of "[email protected]", then click Add, to create an email client.
- Add the key of "EMAIL_HOST_PASSWORD" and the value of "...email password...", then click Add, to create an email client.
- Set the app to automatically deploy from GitHub by selecting GitHub on the Deploy tab.
- Enter the repository name (FS-MS-Project-Build-a-Buffet ) and click Search.
- Click Connect next to the repository name.
To push to Heroku from GitPod (from the command line...)
- pip3 freeze --local > requirements.txt to create a requirements file.
- echo web: python run.py > Procfile to create a Procfile.
- npm install -g heroku
- heroku login -i (enter Heroku credentials)
- git remote add heroku https://git.heroku.com/build-a-buffet.git
- heroku ps:scale web=1
- git push -u heroku master
- From the FS-MS-Project-Build-a-Buffet repository in Github, click ‘Clone or download’.
- Copy the URL to your clipboard.
- In Gitpod, open the terminal.
- Change the directory to that where you wish to place the files.
- Type ‘git clone’ then paste the URL.
- Type into the command line:
- pip3 install Django
- pip3 install django-allauth
- pip3 install pillow
- pip3 install django-crispy-forms
- pip3 install django-countries
- pip3 install dj-database-url
- pip install psycopg2-binary
- pip install psycopg2
- pip install gunicorn
- pip3 install boto3
- pip3 install django-storages
- pip3 install stripe
- python3 manage.py runserver
Alternatively, type "pip install -r requirements.txt" to install all addins from requirements file, then "python3 manage.py runserver".
- The formula (calc(10px + (48 - 10) * ((100vw - 300px) / (1800 - 300)))) for responsive font sizing is from css-tricks and made by Mike
- The method for aligning text vertically is from webdevblog
- The method to adjust styling based on landscape or portrait orientation is from stackoverflow
- The slider is from w3schools
- Creating a cookie in javascript is from w3schools
- Passing context from Django to Javascript is from stackoverflow
- Inserting a row into a database with Django is from stackoverflow
- ObjectDoesNotExist: is from stackoverflow
- Get a single objects value is from http://morozov.ca
- Using aggregate and dict is from stackoverflow.com
- Django model.AutoField is from www.fullstackpython.com
- Order by ascending and descending is from stackoverflow.com and stackoverflow.com
- Limit number to 2 decimals is from tutorialdeep.com
- Getting the current user is from stackoverflow.com
- Using an hr to mimic a br is from stackoverflow.com
- Formatting date is from ourcodeworld.com
- Getting the first row from a queryset is from stackoverflow.com
- Combining two or more querysets is from stackoverflow.com
- Getting the image from the Django form is from stackoverflow.com
- Making a form field readonly is from stackoverflow.com
- Get the last n chacters of a string is from c-sharpcorner.com
- Converting to string in templete is from stackoverflow.com
- Adding linebreaks to messages is from stackoverflow.com
- Sending html email is from stackoverflow.com
- Making a div appear for 2 seconds is from stackoverflow.com
- Form validation is from javascripttutorial.net
- Fixing the uncaught error in the navbar is from stackoverflow.com
- Getting a random sample from the dataset is from stackoverflow.com
- Formatting to 2 decimal points is from stackoverflow.com
The code for:
- checkout: admin.py, forms.py, models.py, views.py, checkout.css and stripe_elements.js
- profiles: forms.py, models.py and views.py are all built upon code from the Code Institute tutorial project 'boutique-ado'
- All images were taken from pexels.com
- The image for Bartholemew was purchased on licence from gettyimages
- The allergy graphics were purchased on licence from gettyimages
I would like to thank the following people for thier support and input:
- My mentor, Precious Ijege for his knowledge and clear direction (it was he who made it very clear that a detailed set of mockups were vital - this is knowledge I will keep with me for the rest of my career!)
- My friends Scott and Magoo, who I consulted before I started the FSD course, and gave me the confidence to go for it!
- Annie for being the most supportive person ever!