ProFit-PT is an e-commerce website where the customer can hire personal trainers for in person training, creating personalized workout plans, and fitness counseling.
The site includes helpful features such as a profile for registered users, an about page and a contact page.
The profile will help returning customers in faster checkout, and make their order history accessible in one place. The about/contact pages are included to show relevant information about the site, and make contact between customers and site owner(s) simple.
This website was built as a project for the Diploma in Full Stack Software Development at Code Institute.
I started out with Wireframes for both desktop and mobile.
The basic structure for services and service details was created. I did not have any wireframes for the profile/cart/checkout, so I used the CI Boutique Ado walk-through for those pages.
After the base structure for viewing and purchasing services was complete, I moved on the the about/faqs/contact pages. Originally, I had planned for separate pages for all of them, but as the pages started taking shape, I combined some of their functionalities to make related information easier to find.
##4C4C4C
used for primary text.
#f5f5f5
used for primary highlights.
#FFFFFF
used for secondary text.
#4C4C4CBF
used for secondary highlights.
I used coolors.co to generate my colour palette.
Lato was used for all text.
Font Awesome icons were used throughout the site, such as the search icon and tag icon for categories.
As a customer I can register an account so that I can log in, and use the site in an authorized and secure way.
As a customer I can receive a email confirmation after account registration so that I know that my registration was successful.
As a customer I can log in with my account information so that I can fully use the sites features.
As a customer I can log out from my account so that I can avoid unauthorized access to my data.
As a customer I can view services so that I can see the sites supply.
As a customer I can view service details so that I can see detailed service information and make informed purchasing decisions.
As a customer I can search for a service by name or description so that I can find a specific service I'd like to purchase.
As a customer I can sort the list of services so that I can easily identify the product I might be interested in.
As a customer I can add services to my shopping cart, view the contents of my cart and proceed to checkout, so that I can complete my purchase quickly and easily.
As a customer I can proceed to checkout/payment so that I can pay for my services and enter my delivery information.
As a customer I can receive a purchase confirmation e-mail so that I know that my order was successful.
As a customer I can access my profile so that add/review information about my account.
As a customer I can save my information so that I can have a faster checkout process when coming back to the site.
As a customer I can view my order history so that I can track my purchases.
As a customer I can fill out a contact form so that I can send messages to the site admin.
As a customer I can find a FAQ section so that I can easily find answers to common questions regarding the site.
As a customer I can sign up for a newsletter so that I can receive the latest news and deals.
As a site admin I can moderate users and their data in the admin dashboard so that I can make changes when required.
As a site admin I can receive a contact form so that I can have direct contact with the customers.
As a site admin I can mark contact messages as "read" so that I can keep track on which messages I have reviewed.
As a site admin I can add/edit/delete FAQs so that I can make the site easier to use for the customer.
As a site admin I can add/edit/delete services so that I can manage my service inventory.
Wireframes were developed for mobile and desktop sizes.
I've used Balsamiq to design my site wireframes.
#1 Header with Logo home redirect
#2 Navbar links to "Our Services" in drop-down menu
#3 Navbar links to Home, About and Contact section
#4 Search field
#5 "My Account" drop-down menu
#6 Cart display
#7 Site Banner
#8 Feedback messages
#9 Landing page
#10 Our services cards
#11 Service cards edit/delete links (ADMIN ONLY)
#12 Service cards Read More link
#13 Service details
#14 Add service (ADMIN ONLY)
#15 Edit service (ADMIN ONLY)
#16 Shopping Cart
#17 Checkout
#18 Checkout success page
#19 User registration
#20 User Sign in
#21 User Log out
#22 User Profile
#23 About page
#24 Contact page
#25 Mobile Navbar
#26 404-page
#27 Admin user management
#28 Admin contact management
#29 Admin FAQ management
#1 Front end pricing tier creation
used as the front-end CSS framework for modern responsiveness and pre-built components.
used for online secure payments of ecommerce products/services.
used to help debug, troubleshoot, code suggestions and explain things.
Initial ERD:
Entity Relationship Diagrams (ERD) help to visualize database architecture before creating models.
Understanding the relationships between different tables can save time later in the project.
I have used pygraphviz
and django-extensions
to auto-generate an ERD.
The steps taken were as follows:
In the terminal: sudo apt update
then: sudo apt-get install python3-dev graphviz libgraphviz-dev pkg-config
then type Y
to proceed
then: pip3 install django-extensions pygraphviz
in my settings.py
file, I added the following to my INSTALLED_APPS
:
INSTALLED_APPS = [
...
'django_extensions',
...
]
back in the terminal: python3 manage.py graph_models -a -o erd.png
dragged the new erd.png
file into my documentation/
folder
removed 'django_extensions',
from my INSTALLED_APPS
finally, in the terminal: pip3 uninstall django-extensions pygraphviz -y
source autogenerated ERD: medium.com
erDiagram
FAQs {
int id PK
string question
text answer
}
Newsletter {
int id PK
string email
}
Order {
int id PK
string order_number
datetime date
string full_name
string email
string phone_number
string country
string postcode
string town_or_city
string street_address1
string street_address2
string county
decimal grand_total
text original_cart
string stripe_pid
int user_profile_id FK
}
OrderLineItem {
int id PK
decimal lineitem_total
int order_id FK
int service_id FK
int pricingtier_id FK
}
Contact {
int id PK
string name
string email
text message
boolean read
}
UserProfile {
int id PK
string default_phone_number
string default_street_address1
string default_street_address2
string default_town_or_city
string default_county
string default_postcode
string default_country
int user_id FK
}
Category {
int id PK
string name
string friendly_name
}
Service {
int id PK
string name
text description
string image
int category_id FK
}
PricingTier {
int id PK
int quantity
decimal price_per_unit
}
Order ||--o{ OrderLineItem : contains
UserProfile ||--o{ Order : places
Service ||--o{ OrderLineItem : available
PricingTier ||--o{ OrderLineItem : sets
Category ||--o{ Service : categorizes
Service }o--o{ PricingTier : has
source interactive ERD: mermaid.live
GitHub Projects served as an Agile tool for this project.
It isn't a specialized tool, but with the right tags and project creation/issue assignments, it can be made to work.
Through it, user stories, issues, and milestone tasks were planned, then tracked on a weekly basis using the basic Kanban board.
GitHub Issues served as an another Agile tool.
There, I used my own User Story Template to manage user stories.
It also helped with milestone iterations on a weekly basis.
I've decomposed my Epics into stories prior to prioritizing and implementing them.
Using this approach, I was able to apply the MoSCow prioritization and labels to my user stories within the Issues tab.
Must Have: guaranteed to be delivered (max 60% of stories)
Should Have: adds significant value, but not vital (the rest ~20% of stories)
Could Have: has small impact if left out (20% of stories)
Won't Have: not a priority for this iteration
This site sells goods to individual customers, and therefore follows a Business to Customer
model.
It is of the simplest B2C forms, as it focuses on individual transactions, and doesn't need anything such as monthly/annual subscriptions.
It is still in its early development stages, although it already has a newsletter, and links for social media marketing.
Social media can potentially build a community of users around the business, and boost site visitor numbers, especially when using larger platforms such a Facebook.
A newsletter list can be used by the business to send regular messages to site users.
For example, what items are on special offer, new items in stock, updates to business hours, notifications of events, and much more!
I've identified some appropriate keywords to align with my site, that should help users when searching online to find my page easily from a search engine.
This included a series of the following keyword types
I also played around with Word Tracker a bit to check the frequency of some of my site's primary keywords (only until the free trial expired).
I've used XML-Sitemaps to generate a sitemap.xml file.
This was generated using my deployed site URL: https://pro-fit-pt-dcb56d3b7224.herokuapp.com
After it finished crawling the entire site, it created a sitemap.xml which I've downloaded and included in the repository.
I've created the robots.txt file at the root-level.
Inside, I've included the default settings:
User-agent: *
Disallow:
Sitemap: https://pro-fit-pt-dcb56d3b7224.herokuapp.com/sitemap.xml
Further links for future implementation:
Creating a strong social base (with participation) and linking that to the business site can help drive sales.
Using more popular providers with a wider user base, such as Facebook, typically maximizes site views.
I've created a Facebook business account.
I have incorporate a newsletter sign-up form on my application, to allow users to supply their email address if they are interested in learning more.
[!NOTE] For all testing, please refer to the TESTING.md file.
The live deployed application can be found deployed on Heroku.
This project uses a Code Institute PostgreSQL Database.
To obtain my own Postgres Database from Code Institute, I followed these steps:
Signed-in to the CI LMS using my email address.
An email was sent to me with my new Postgres Database.
[!CAUTION]
- PostgreSQL databases by Code Institute are only available to CI Students.
- You must acquire your own PostgreSQL database through some other method if you plan to clone/fork this repository.
- Code Institute students are allowed a maximum of 8 databases.
- Databases are subject to deletion after 18 months.
This project uses Whitenoise to store static files online, due to the fact that Heroku doesn't persist this type of data.
To install whitenoise, run the pip install whitenoise
command.
Edit your settings.py file and add WhiteNoise to the MIDDLEWARE list. The WhiteNoise middleware should be placed directly after the Django SecurityMiddleware (if you are using it) and before all other middleware:
MIDDLEWARE = [
# ...
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
# ...
]
This project uses Cloudinary for online static file storage.
To install Cloudinary, run the pip install cloudinary
and pip install dj3-cloudinary-storage
commands.
Edit your settings.py file and add cloudinary_storage and cloudinary to the INSTALLED_APPS list. Note that cloudinary_storage should be placed directly after the django.contrib.staticfiles.
INSTALLED_APPS = [
# ...
"django.contrib.staticfiles",
"cloudinary_storage",
# ...
"cloudinary",
]
To sign up for cloudinary, visit Cloudinary.com.
Once you've created a Cloudinary account and logged-in, follow these series of steps to get your project connected.
CLOUDINARY_URL=cloudinary://<your_api_key>:<your_api_secret>@<your_cloud_name>
This project uses Stripe to handle the ecommerce payments.
Once you've created a Stripe account and logged-in, follow these series of steps to get your project connected.
From your Stripe dashboard, click to expand the "Get your test API keys".
You'll have two keys here:
STRIPE_PUBLIC_KEY
= Publishable Key (starts with pk)
STRIPE_SECRET_KEY
= Secret Key (starts with sk)
As a backup, in case users prematurely close the purchase-order page during payment, we can include Stripe Webhooks.
From your Stripe dashboard, click Developers, and select Webhooks.
From there, click Add Endpoint.
https://pro-fit-pt-dcb56d3b7224.herokuapp.com/checkout/wh/
Click receive all events.
Click Add Endpoint to complete the process.
You'll have a new key here:
STRIPE_WH_SECRET
= Signing Secret (Wehbook) Key (starts with wh)
This project uses Gmail to handle sending emails to users for account verification and purchase order confirmations.
Once you've created a Gmail (Google) account and logged-in, follow these series of steps to get your project connected.
Click on the Account Settings (cog icon) in the top-right corner of Gmail.
Click on the Accounts and Import tab.
Within the section called "Change account settings", click on the link for Other Google Account settings.
From this new page, select Security on the left.
Select 2-Step Verification to turn it on. (verify your password and account)
Once verified, select Turn On for 2FA.
Navigate back to the Security page, and you'll see a new option called App passwords.
This might prompt you once again to confirm your password and account.
Select Mail for the app type.
Select Other (Custom name) for the device type.
Any custom name, such as "Django" or pro-fit-pt
You'll be provided with a 16-character password (API key).
Save this somewhere locally, as you cannot access this key again later!
EMAIL_HOST_PASS
= user's 16-character API key
EMAIL_HOST_USER
= user's own personal Gmail email address
This project uses Heroku, a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.
Deployment steps are as follows, after account setup:
Select New in the top-right corner of your Heroku Dashboard, and select Create new app from the dropdown menu.
Your app name must be unique, and then choose a region closest to you (EU or USA), and finally, select Create App.
From the new app Settings, click Reveal Config Vars, and set your environment variables.
[!IMPORTANT] This is a sample only; you would replace the values with your own if cloning/forking my repository.
Key | Value |
---|---|
CLOUDINARY_URL |
user's own value |
DATABASE_URL |
user's own value |
DISABLE_COLLECTSTATIC |
1 (this is temporary, and can be removed for the final deployment) |
EMAIL_HOST_PASS |
user's own value |
EMAIL_HOST_USER |
user's own value |
SECRET_KEY |
user's own value |
STRIPE_PUBLIC_KEY |
user's own value |
STRIPE_SECRET_KEY |
user's own value |
STRIPE_WH_SECRET |
user's own value |
Heroku needs three additional files in order to deploy properly.
requirements.txt
Procfile
runtime.txt
You can install this project's requirements (where applicable) using:
pip3 install -r requirements.txt
If you have your own packages that have been installed, then the requirements file needs updated using:
pip3 freeze --local > requirements.txt
The Procfile can be created with the following command:
echo web: gunicorn app_name.wsgi > Procfile
replace app_name with the name of your primary Django app name; the folder where settings.py is located
The runtime.txt file needs to know which Python version you're using:
type: python3 --version
in the terminal.
in the runtime.txt file, add your Python version:
python-3.9.19
For Heroku deployment, follow these steps to connect your own GitHub repository to the newly created app:
Either:
Or:
In the Terminal/CLI, connect to Heroku using this command: heroku login -i
Set the remote for Heroku: heroku git:remote -a app_name
(replace app_name with your app name)
After performing the standard Git add
, commit
, and push
to GitHub, you can now type:
git push heroku main
The project should now be connected and deployed to Heroku!
This project can be cloned or forked in order to make a local copy on your own system.
For either method, you will need to install any applicable packages found within the requirements.txt file.
pip3 install -r requirements.txt
.You will need to create a new file called env.py
at the root-level,
and include the same environment variables listed above from the Heroku deployment steps.
[!IMPORTANT] This is a sample only; you would replace the values with your own if cloning/forking my repository.
Sample env.py
file:
import os
os.environ.setdefault("CLOUDINARY_URL", "user's own value")
os.environ.setdefault("DATABASE_URL", "user's own value")
os.environ.setdefault("EMAIL_HOST_PASS", "user's own value")
os.environ.setdefault("EMAIL_HOST_USER", "user's own value")
os.environ.setdefault("SECRET_KEY", "user's own value")
os.environ.setdefault("STRIPE_PUBLIC_KEY", "user's own value")
os.environ.setdefault("STRIPE_SECRET_KEY", "user's own value")
os.environ.setdefault("STRIPE_WH_SECRET", "user's own value")
# local environment only (do not include these in production/deployment!)
os.environ.setdefault("DEBUG", "True")
Once the project is cloned or forked, in order to run it locally, you'll need to follow these steps:
Start the Django app: python3 manage.py runserver
Stop the app once it's loaded: CTRL+C
or ⌘+C
(Mac)
Make any necessary migrations: python3 manage.py makemigrations
Migrate the data to the database: python3 manage.py migrate
Create a superuser: python3 manage.py createsuperuser
Load fixtures (if applicable): python3 manage.py loaddata file-name.json
(repeat for each file)
Everything should be ready now, so run the Django app again: python3 manage.py runserver
If you'd like to backup your database models, use the following command for each model you'd like to create a fixture for:
python3 manage.py dumpdata your-model > your-model.json
repeat this action for each model you wish to backup
You can clone the repository by following these steps:
Go to the GitHub repository
Locate the Code button above the list of files and click it
Select if you prefer to clone using HTTPS, SSH, or GitHub CLI and click the copy button to copy the URL to your clipboard
Open Git Bash or Terminal
Change the current working directory to the one where you want the cloned directory
In your IDE Terminal, type the following command to clone my repository:
git clone https://github.com/DavidFB94/pro-fit-pt.git
Alternatively, if using Gitpod, you can click below to create your own workspace using this repository.
Please note that in order to directly open the project in Gitpod, you need to have the browser extension installed.
A tutorial on how to do that can be found here.
By forking the GitHub Repository, we make a copy of the original repository on our GitHub account to view and/or make changes without affecting the original owner's repository.
You can fork this repository by using the following steps:
Log in to GitHub and locate the GitHub Repository
At the top of the Repository (not top of page) just above the "Settings" Button on the menu, locate the "Fork" Button.
Once clicked, you should now have a copy of the original repository in your own GitHub account!
There are no significant differences between local vs deployed version.
The core e-commerce functionalities and templates (services + checkout flow + alerts + payments) in this project was set up following Code Institutes walk-through. After the core functionalities were in place, adjustments were made to accommodate my design for the site.
Source | Location | Notes |
---|---|---|
Markdown Builder | README and TESTING | tool to help generate the Markdown files |
Djangoproject | views | Setting up Django messages |
Djangoproject | views | Using distinct() for fetching unique service |
Bootstrap5 | Page layout | Using Bootstrap grid system |
Bootstrap5 | main-nav.html | navbar with dropdown |
Bootstrap5 | services + service details | interactive pop-up (modal) for delete confirmation |
Bootstrap5 | services + service details | card layout |
Bootstrap5 | about | FAQs accordion |
WhiteNoise | entire site | hosting static files on Heroku temporarily |
Cloudinary | services + service details | how to use cloudinary field |
ChatGPT | entire site | to help me troubleshoot a few bugs I had, as well as explain some coding concepts used from the walkthrough lesson |
Source | Location | Type | Notes |
---|---|---|---|
Freepik | home page | image | Background image |
Pexels | services + service details | image | Counseling image |
Pexels | services + service details | image | PT Weightlifting image |
Pexels | services + service details | image | PT Wellness image |
Unsplash | services + service details | image | PT Power-lifting image |
iStockphoto | services + service details | image | PT Athletics image |
StockAdobe | services + service details | image | No image placeholder |
Bodybuilding | services + service details | image | PT Bodybuilding image |
Canva | services + service details | image | Workout plan image |
Fontawesome | entire site | icons | Icons for profile, cart, search, category tag etc.. |
I would like to thank my Code Institute mentor, Tim Nelson for his support throughout the development of this project.
I would like to thank the Code Institute tutor team for their assistance with troubleshooting and debugging some project issues.
I would like to thank my wife Maria for believing in me, and allowing me to make this transition into software development.