Vibrant Teas is a B2C e-commerce website that sells organic teas and tea accessories. The site is aimed at tea lovers who care about the products they consume being organic and where they are being sourced from. This is a full-stack site with an authentication mechanism. The site was created using HTML, CSS, JavaScript, Django and Python.
The goal of the project is to create a fully functional e-commerce website that is simple and easy to use. allowing users to register, login, logout, view products, add to cart, submit payment information and checkout successfully. The site will have two main product categories which are tea and tea accessories and will be further divided into subcategories for different types of teas and different types of teas accessories. All the teas offered on the site will have additional information on the producers of the tea to allow users to have the transparency of knowing where their teas are being sourced from. Added features will be available on the site such as a contact page for users to reach out to the store owner and the ability for users to add, delete and edit their reviews.
The website is targeted at tea lovers who like to consume natural, organic ingredients. People who place high importance on company transparency and want to know where to products they consume are being produced are sourced from.
When it came to planning the project I used agile development methodologies to plan the project. I used EPICS to break down the project into different key functionalities of the site. The User stories were then added to the relevant Epics, and then the Epics were delivered over a set of sprints. The MoSCoW model was used to prioritize different features, by classifying them as Must, Should, Could, and Won't. I made sure this was organised so that the core functionality of the site was working properly before additional features were added if there was scope to do so. I used a Kanban board to work through the different user stories. I mapped out the information architecture and created wireframes to help me have a strong visualisation of the site. A lot of time was put into planning before I began coding to allow me to properly organise how I would work through the project.
- View the list of products available so that I can see what the store has to offer and select some to purchase
- View individual product details so that I can identify the price, description, product reviews, product image and availability
- Easily view the total of my purchases at any time so that I can avoid spending too much
- See a list of all the producers so that I can see where all the products are coming from
- See the specific producers for each product so that I can see where that specific product comes from
- See the testimonials so that I can see other people's experiences shopping from the site
- Subscribe to a newsletter so that I can receive updates about the store products
- Contact the store so that I can get more information on products
- See alerts when I complete an action so that I can know if it has been completed or if it didn't go through
- Easily register for an account so that I can have a personal account and be able to view my profile
- Easily log in or log out so that I can access my account information
- Easily recover my password in case I forget so that I can recover access to my account
- Receive an email confirmation after registering so that I can verify that my account registration was successful
- Have a personalised user profile so that I can view my order history and order confirmations and save my contact information
- Update my details so that I can keep them updated
- Search for a product by name or description so that I can find a specific product I would like to purchase
- Sort the list of available products so that I can easily identify the best price and categorically sorted products
- View items in my bag to be purchased so that I can identify the total cost of my purchase and all items I will receive
- Adjust the quantity of individual items in my bag so that I can easily make changes to my purchase before checkout
- Easily enter my payment information so that I can checkout quickly and with no hassles
- Feel my personal and payment information is safe and secure so that I can confidently enter the needed information to make a purchase
- View an order for confirmation after checkout so that I can verify that I haven't made any mistakes
- Receive an email confirmation after checkout so that I can keep the confirmation of what I've purchased for my records
- Add a product so that I can add new items to my store
- Edit and update a product so that I can change product prices, descriptions, images, and other product criteria
- Delete a product so that I can remove items that are no longer available
- Leave a review so that I can give my feedback on a product
- View product reviews so that I can see other peoples opinions of the products
- Edit my product review so that I can make changes to my review
- Delete my product reviews so that I can so that I can remove my previous reviews if I no longer want them up
I used DrawSQL to create a diagram of the models
The font used throughout the entire site was Roboto, sans-serif and it was sourced from Google fonts. The reason I chose this font was because of its simple look and because it was easy to read.
I chose to go for more earth-toned colours that reflected different herbal teas, using the main hero image on the page as a template for the types of colours I wanted throughout the entire site. The colours range from cream, to warm golds and oranges, earthy greens and dark reds. The colour palette I generated is available at Coolors
To showcase the theme of the site I designed a logo that has a teapot and cup with the company name and organic written underneath it.
Wireframes were created using Balsamiq wireframes to help visualise how the site would look and feel.
- Home Page Wireframe
- Products Page Wireframe
- Products Detail Page Wireframe
- Review Page Wireframe
- Producers Page wireframe
- Product Management Page Wireframe
- User Profile Page Wireframe
- Shopping Bag Page Wireframe
- Checkout Page Wireframe
- Registration Page Wireframe
- Login Page Wireframe
- Logout Page Wireframe
- Contact Page Wireframe
The navigation bar sits at the top of all the pages. It has a free delivery threshold banner so users are aware of the free delivery offer over a certain amount. It also has a search bar so a user can search for products throughout the site. From the navigation, the user can access all the products available in the store. The navigation bar contains links for all products, teas, accessories, producers, contact, account and bag. The tea button displays a drop-down menu for the subcategories which are herbal tea, green tea and black tea. The Accessories button also displays a drop-down menu for the subcategories which are tea strainers and teaware. The account button displays a drop-down menu, providing links for registration, login, logout, profile and product management. The product management button is only available if a user is logged in as a super user. On mobile or tablet screens the header navigation collapses.
The home page was kept very simple. It has a header image that shows glass jars with different teas in each of them on a table. The Colours of the teas in the image inspires the overall colour and theme of the site. The home page has a welcome page which gives a brief introduction to the company, what types of products are offered and a link to view all products. Below the intro are links to 3 of the product pages. There is also a testimonial section below that offers the user the ability to see feedback from people who have shopped on the site and learn about their experiences.
The footer is split into two key areas. The first area of the footer is the Newsletter signup where a user can enter their email address to receive news and updates on the website and products. Below is the second part of the footer which contains social media links, contact information and useful links to the products pages, the producers' page, the contact form and the site privacy policy.
The products page displays all the products available, both the teas and accessories. If from the navigation the user selects a specific subcategory they will be brought to a page that just shows all the products in the specific category they selected. From the products page, the user can sort the products displayed by price, name and category. If a superuser is logged in below the product price they will have two additional options to either edit the product where they will be redirected to the product management page or delete the product in which a delete confirmation will pop up asking them if they are sure they want to delete the product.
The product details page provides more information on the product. It shows the product image to the left and on the right all the information. It provides the subcategory of the product, the name, the price, weight, the product description, and a button labelled producers that opens up to show the details of the product's producer. The information displayed for the product is different depending on the product category. Two specific pieces of information are only relevant for teas so only appear for teas and their subcategories, which are the weight and the producer button. As the weight and producers aren't relevant for accessories when you click on an accessory those two pieces of information will not be there. The user can select the quantity or the product they want and add it to the bag or have the option of returning to the main products page. Below the product's image and details is a section from reviews. This is where a user can see all the reviews for the product and add their review. If they are not logged into the site they will be asked to sign in to leave a review. They will have two buttons to either register or log in. If a user is already logged in they will see a button to add their review, where they can give a star rating and add details. A user also can delete or edit their review
If a superuser is logged in, below the product image they will have two additional options to either edit the product where they will be redirected to the product management page or delete the product in which a delete confirmation will pop up asking them if they are sure they want to delete the product.
The Producers page offers information on the different types of producers the company works with to source their teas. It provides the name of the producer, the location of the producer and some background. This gives users fuller transparency on where they are getting their products from.
The contact page is a simple contact form where a user can input their name and email and send a message to the site owner, to get more information or ask any questions they may have.
When a user adds a product to the shopping bag a mini order summary will display underneath the bag icon with the product they added, the price and how much more they need to spend to get free delivery. When the user clicks on the bag they will be taken to the shopping back page where they will see the products they added to their bag. They can change the quantity of the product in their bag and update it or remove an item from their bag to the bottom of the page they will be given the bag total, delivery, and total and two options to either keep shopping and return to the products page or go to secure checkout.
Once the secure checkout button has been selected the user will be taken to the secure checkout page. It will show a summary of their order and they will be able to input their details on the checkout form. If the user has delivery details saved on their profile, the information will auto-populate into the form but they will still be able to change their details if they want to. They have a tick button option below the form to save their delivery information to their form. Below the form is a stripe payment field for users to input their payment card details. Below that they have two options to either return to the shopping bag to adjust their order or complete the order.
Once the user has completed their secure checkout their order will be processed and they will be taken to a thank you page with their order confirmation. They will have a note saying their confirmation email has been sent to their email address. The order confirmation will display the order number, order date, order details, and delivery and billing info.
When a user is logged in they will be able to access their profile. Their profile has their default delivery information saved which they can update. Their profile will also have a list of all their previous orders. If they click on an order number they will be taken to that orders confirmation page with details on the order. Below the confirmation page, they will have a button that allows the to return to their profile.
The product management page can only be accessed by super users. It provides a form where a superuser can add a new product without having to go through the admin panel. They can select the product category, and subcategory and input all the relevant product details.
When a user goes to the login page they can login with their username or email address.
When the user clicks on the logout page they are directed to a confirmation page, where they can either cancel or continue to log out.
The user can register for an account by inputting their email address twice, inputting a username and inputting their passwords twice.
In order the make sure that the site is accessible through search engines a sitemap and robots.txt file were created to allow search engines to crawl through the site and fetch relevant content to assist with SEO. Relevant keywords were used in the meta tags of the HTML. Newsletter signup was created using Mailchimp and placed at the footer of the page to allow users to stay up to date with the updates on the site. A Facebook business page was created to help promote the site to target consumers which had the site branding. Having a Facebook page offers great advertising potential with its use of Facebook ads and content creation for the brand.
A full breakdown of site testing can be found in a separate document called TESTING.md
The live deployment can be found using the following URL - https://vibrant-teas.herokuapp.com/
- Log in to ElephantSQL.com and access the dashboard
- Click “Create New Instance”
- Set up a plan
- Give the plan a Name
- Select the Tiny Turtle (Free) plan
- Can leave the Tags field blank
- Select “Select Region”
- Select a data centre near you
- EU-West-1 (Ireland)
- Then click “Review”
- Check details are correct and then click “Create instance”
- Return to the ElephantSQL dashboard and click on the database instance name for this project
- In the URL section, clicking the copy icon will copy the database URL to your clipboard
I deployed this project in Heroku using the following steps:
- Log In to Heroku
- From the Heroku dashboard, click on "New" and in the drop-down click "Create new app"
- Create a unique name for the project, select your region and click "Create app"
- Navigate to the Settings tab
- Scroll down to config var and click on "Reveal Config Vars"
- Add Database URL from Elephant SQL
- Navigate to Gitpod and in the terminal, install dj_database_url and psycopg2, both of these are needed to connect to your external database.
- Update your requirements.txt file with the newly installed packages
- In your settings.py file, import dj_database_url underneath the import for os
- Scroll to the DATABASES section, comment out the original connection to sqlite3 and connect the new Elephant SQL database by pasting in the URL
- In the terminal, run the show migrations command to confirm you are connected to the external database
- If you are, you should see a list of all migrations, but none of them are checked off
- Migrate your database models to your new database
- On the ElephantSQL page for your database, in the left side navigation, select “BROWSER”
- Click the Table queries button, select auth_user
- When you click “Execute”, you should see your newly created superuser details displayed. This confirms your tables have been created and you can add data to your database
- In Gitpod create an if statement in settings.py so that when our app is running on Heroku where the database URL environment variable will be defined. We connect to Postgres and otherwise, we connect to SQLite.
if 'DATABASE_URL' in os.environ: DATABASES = { 'default': dj_database_url.parse(os.environ.get('DATABASE_URL')) }
- In terminal install gunicorn
- Freeze requirements.txt
- Create Procfile to tell Heroku to create a web dyno, which will run gunicorn and serve Django app
- In terminal login to Heroku
- Temporarily disable collect static so Heroku will not collect static files when we deploy
- Add the hostname of our Heroku app to ALLOWED_HOSTS in settings.py and localhost so gitpod will work too
- Add and commit changes in the terminal and push
- Git push Heroku main to deploy to Heroku
- Go to app in the Heroku app and navigate to the Deploy tab at the top of the page
- Go to the deployment method and select "GitHub"
- Confirm you want to connect to GitHub by clicking "Connect to GitHub"
- Insert repository name and click "Search"
- Click "Connect" to link up Heroku app to the GitHub repository code
- Scroll down and choose a deployment method
- Click on "Enable Automatic Deploys"
- This allows Heroku to rebuild your app every time you push a new change to your code to GitHub
- Generate a Secret Key and add it to config var
- Return to settings.py in gitpod and replace the secret key setting with a call to get it from the environment and use an empty string as a default
SECRET_KEY = os.environ.get('SECRET_KEY', '')
- Set DEBUG to be true only if there is a development in the environment
DEBUG = 'DEVELOPMENT' in os.environ
- Commit changes and push to github
- Create AWS account
- Go to AWS Management Console and search for S3 service
- Create a Bucket to store your files
- Name your bucket to match your Heroku app name
- Select region, choose the one closest to you
- Uncheck the box 'Block All Public Access'
- Click on Create Bucket, and your bucket is created
- Click on your newly created bucket, and navigate to the Properties tab
- Scroll down to Static Website Hosting and click edit
- Click enable
- Choose host a Static Website
- Index document: index.html
- Error document: error.html
- Click Save Changes
- Navigate to the Permissions tab. Scroll down to Cross-origin resource sharing (CORS) and click on edit. Paste in this Cors Configuration below, which is going to set up the required access between the Heroku app and this S3 bucket. Click on Save Changes.
[ { "AllowedHeaders": [ "Authorization" ], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ]
- Still within the Permissions tab, scroll down to the Bucket policy, click on Edit, and then go to Policy Generator.
- Select Policy S3 Bucket Policy,
- Effect: choose Allow
- Principal: *
- Actions: select GetObject
- Copy in the Amazon Resource Name (ARN), from the Bucket ARN back in the Bucket Policy
- Click on the Add Statement and then Generate Policy.
- Copy the policy and paste it into the bucket policy editor
- Add a slash star to the end of the resource key
- Click Save.
- Still within the Permissions tab, scroll down to the Access Control List (ACL) section, click Edit and enable List for Everyone (public access), and select the warning box understanding the effects the changes may have on your objects and buckets
- With the S3 bucket ready to go now you need to create a user to access it. This can be done through a service called IAM (Identity and Access Management).
- Go back to the service menu and open IAM
- Click on Groups and create a new group, naming it what you want e.g. manage-site-name. Click next step, then next step again and then create a group
- Click on Policies and then Create Policy.
- Go to the JSON tab, and then select import managed policy, which will let us import one that AWS has pre-built for full access to S3. Search for S3, then import the AmazonS3FullAccess policy.
- As we only want to allow full access to our new bucket and everything within it, paste the bucket ARN (from the bucket policy page in s3) in the JSON editor beside Resource.
- Click Review Policy, give it a name and a description, then click Create Policy. The policy has now been created.
- Attach the policy to the group that was created by going to groups.
- Select the group.
- Go to the Permissions tab, open the Add Permissions dropdown, and click Attach Policies.
- Select the policy and click Add permissions at the bottom.
- Create a user to put in the group, by going to the Users page, and clicking Add Users.
- Set a user name, give them access type: Programmatic access, and then click Next: Permissions
- Check on the group that has the policy attached. Click Next: Tags, then click Next: Review, and lastly Create User.
- Download the csv file and save it.
- Install two new packages: boto3 and django-storages. Freeze them into requirements.txt.
pip3 install boto3 pip3 install django-storages pip3 freeze > requirements.txt
- Add storages to the Installed Apps in settings.py
- In settings.py, we need ad an if statement to set cache control, set bucket configurations, set static and media files location, and override static and media URLs in production.
if 'USE_AWS' in os.environ: # Cache control AWS_S3_OBJECT_PARAMETERS = { 'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT', 'CacheControl': 'max-age=94608000', } # Bucket Config AWS_STORAGE_BUCKET_NAME = 'YOUR_BUCKET_NAME' AWS_S3_REGION_NAME = 'YOUR_REGION' AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY') AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com' # Static and media files STATICFILES_STORAGE = 'custom_storages.StaticStorage' STATICFILES_LOCATION = 'static' DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage' MEDIAFILES_LOCATION = 'media' # Override static and media URLs in production STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{STATICFILES_LOCATION}/' MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{MEDIAFILES_LOCATION}/'
- Add AWS keys to the Config Vars in Heroku
- AWS_ACCESS_KEY_ID = ......
- AWS_SECRET_ACCESS_KEY = ......
- USE_AWS = True
- Remove the COLLECTSTATIC variable from the Config Vars
- We then want to tell Django that in production we want to use S3 to store our static files whenever someone runs collectstatic and that we sent any uploaded images to go there as well.
- Create a custom_storages.py file in your project's root directory, and inside it, include the Static and Media Storage locations:
from django.conf import settings from storages.backends.s3boto3 import S3Boto3Storage class StaticStorage(S3Boto3Storage): location = settings.STATICFILES_LOCATION class MediaStorage(S3Boto3Storage): location = settings.MEDIAFILES_LOCATION
- Commit and push changes
- Python
- HTML
- CSS
- Bootstrap 4
- Django
- AWS
- Heroku
- Elephant SQL
- Stripe
- Mailchimp
- Footer code is taken from MD Bootstrap
- Testimonials section code is taken from BB Bootstrap
- Modal Code is taken from Get Bootstrap
- Code Inspirations from - CI Student Dissy Ulina
- Code Inspiration from - CI Student Lucy Woodman
- Stack Overflow
- Slack
- Student Support
- Pictures were taken from the open source site Unsplash - https://unsplash.com/ and Pexels - https://www.pexels.com/
- Richard Wells Code Institute Mentor.