Skip to content

My final milestone project for my Code Institute course.

Notifications You must be signed in to change notification settings

NicBritz/turn-games

Repository files navigation

Overview

Home page

turn games is an e-commerce digital video game store, the site offers a wide variety of visual entertainment content. Users can browse the sites extensive inventory and filter down the content for easier navigation. Users are also able to search the site by the use of a search bar that is always readily available.

The landing page will show any content that the site owner has added to the featured or discounted sections. It will randomly select ten titles to display on the main page image slider.

Users are easily able to view more information about the game simply by selecting the content card. In the game inspection area, a user can either rate a game with a thumbs up or a thumbs down and add the game to their basket for purchase once they have finished browsing. You can view the site by following this link.

Table of Contents


UX

User Stories

Viewing and Navigation

Done As a... I would like to be able to... So that I may...
user view a list of available games. Select some to purchase.
user view individual game details. view the price, description, game rating.
user quickly identify discounts and special offers. take advantage of savings on games that id like to purchase.
user easily View the total of my cart at any time. avoid overspending.

Registration and User Accounts

Done As a... I would like to be able to... So that I may...
user easily register for an account. have a personal account to be able to view my profile.
user easily login or logout. access my account information.
user log into my account using Google. easily access my profile without site registration.
user easily recover my password. recover access to my account if I forget my credentials.
user receive an email confirmation after registering. verify that my account registration was successful.
user have a personalized user profile. view my order history and order confirmations and save my payment information.

Scrolling and Searching

Done As a... I would like to be able to... So that I may...
user sort the list of available games. easily identify the best rated, best-priced games.
user sort by a specific genre of game. find the best-priced or best-rated product in a specific genre.
user sort by a specific category of game. find the best-priced or best-rated product in a specific category.
user sort by a specific game tag. find the best-priced or best-rated product with a specific tag.
user search for a product by name or description. find a specific product I would like to purchase.
user easily see what I have searched for and the number of results. quickly decide whether the product I want is available.

Purchasing and Checkout

Done As a... I would like to be able to... So that I may...
user easily add or remove the game I want to purchase. easily make changes to my purchase before checkout.
user view items in my bag to be purchased. identify the total cost of my purchase and all the games I will receive.
user easily enter my payment information. check out quickly with no hassles.
user feel my personal and payment information is safe and secure. confidently provide the needed information to make a purchase.
user view an order confirmation after checkout. verify that I have not made any errors.
user receive an email confirmation after checking out. keep the confirmation of what I have purchased for my records.

Admin and Store Management

Done As a... I would like to be able to... So that I may...
user add a game. add new games to my store.
user edit a game. change product prices, descriptions, images and other criteria.
user delete a game. remove games that are no longer for sale.
user have access to an admin dashboard. manage users games and orders.
user view any previous order made. see what was purchased and when.
user see a chart with the past 30 days sales. see how the site is doing financially.

Design

The goal of this project was to create a digital game e-commerce store that makes use of Django as its primary technology. The site is designed to be responsive and neat without compromising on the primary goal of selling games. There are subtle visual elements added to purposely attract the eye to important things like discounts and price total.

Wireframes

Before starting the project I used figma to create the wireframe mockups for the project. This was an instrumental step to ensure a clear design direction. The site did not end up looking exactly like the mockups in the end but the general design is visible in the final result.

Home page

Home page

All Games

All Games

Game Details

Game Details

Trello

To keep track of the project I made use of a Trello board. The board was used to keep track of progress add ideas when they spring to mind and keep track of online resources. You can view the board here

Trello Board

Database Schema

The database used for the development of the project was SQLite which was later moved to Heroku using the Postgres add-on. Below is a visualisation of the database schema. Trello Board

Features

The navigation bar

I created a favicon favicon with the logo that I designed for the site, it feels it just gives the site a more finished look.

NAv Menu

The navigation bar was designed to look neat and only show the minimum amount of menu items possible. In a desktop environment, this navigation menu has the logo which is also a link to the home page. I added small coloured icons to give the site a 'gamey feel', as I felt it would be suitable for the sites intended audience. There are dropdown menus to navigate the site and filter through the various game categories and genres. I have also added the account menu here for easy access as well as a shopping cart button that shows the current value if the items in the cart.

NAv Mobile Mobile Menu

When viewing the website on a mobile device the menu completely collapses into an animated hamburger menu. There are some slight changes to the items in the menu on mobile devices, this was a decision made to keep the site neat.

Account Menu

Account Menu

The account menu changes dynamically depending on the following factors:

  • User not logged in

    • Menu displays: login & Register
  • Standard user logged in

    • Title displays: your-usersname
    • Menu displays: Profile & Logout
  • Admin user logged in

    • Title displays: your-usersname
    • Menu displays: Admin Dashboard & Profile & Logout

Shopping Cart button

Account Menu

When choosing to purchase items from the site they will get added to your shopping cart. The button will update its label to display the current value of the games in your cart.

Hovering over the menu on a desktop will present the above-pictured menu, here you can preview the items currently in your cart as well a select an item to link back to it. I decided to exclude this feature from the mobile versions as it was looking a bit cluttered.

Home Page Slider

MAin Slider

Using a CSS library called Flickety I implemented a slider for the home page. I wanted it not only to be responsive but also make use of the ability to drag through slides on mobile devices.

Hovering over a slide will also stop the slides from scrolling automatically. The layout of this slider will also change depending on the device its viewed on, again this was a decision based on keeping the site looking neat.

Game Cards

Game Card

The game cards are the main way a game is chosen to be purchased. I tried to keep them looking as simple as possible. The cards are also direct links to the more detailed game view. The ratings are displayed on the footer of each card as well as the prices. If a card has a discount attached to it there will be a ribbon in the top right corner indicating the discount percent. There will also be a red price indicating the old/new prices.

Content Filtering

Game Card

If a user chooses any filers in the main navigation menu or chooses to search the site for a particular game, they will be presented with a new view. This is essentially a view that contains all the games and it can be sorted in various ways using the sort dropdown. There is also an indication on the current filter ie: Adventure as above picture indicates. Here you will also see the number of results found under the current search criteria by pressing the red cross users can clear all filters.

Game Details

Game Details

The game details page gives the user a final overview of the game. This includes things the description, developer information and any associated tags. These tags, categories and genres are also links so that a user can easily view more games like the one they are currently interested in. This is also where the Buy button resides. clicking this will, of course, add the game you the cart. If a user tries to add more than one of the same game in the cart they will be presented with a message that the game is already in the cart. This is by design as this is essentially a digital app store so you would not buy a game you already own.

In the case of a site administrator using the detailed game view will show an edit button so that the game can easily be edited without having to access the game through the administrator dashboard.

Footer

Footer

The footer is simple by design and only contains some social links. hovering over the links will change their colours to the correct brand-specific colours. Clicking them will open the relevant social page in a new tab.

On mobile devices, the footer has been moved inside the hamburger menu to make use of maximum screen space for site content.

Sign-in

Sign in

The site makes use of Django allauth to handle its user login authentication. I have styled all the standard allauth templates to align with the design of the site. I have also implemented the ability to sign in with your Google account. This makes site registration and login very simple.

User Profile

Profile

The profile page features the ability to add your personal information to make the checkout process faster. From here users can also view all their previous orders and update their email and password. By selecting the order number a user can see a more detailed view of the order.

Shopping cart

Cart

The shopping cart view displays all the games in your cart in detail. from this view, you can start the checkout process or go back to browse the store. Games can also be removed from your cart in this view by selecting the red cross situated to the left of the game's image. There is also an indication of the total value of the items in the cart taking the tax percentage into account.

There is a step indication at the top of the view to show the current progressing the checkout process. By selecting the secure checkout button a user can begin the checkout process.

Checkout View

Checkout

Here a user can fill in their information to make payment for the items in their cart. Required information is indicated with a red asterisk. The credit card section makes use of stripe as the payment technology.

If all the information is correct and the user chooses to submit, then the payment intent will be sent to Stripe for processing. There is a webhook implemented as a precaution against errors during this process. The submit button is disabled and replaced with a loading indicator to show there is an action in progress.

Checkout Success

Checkout

Upon successful completion of the order, a user will be presented with the above success screen. The customer will get an email also at this point confirming their order. If the user is logged in as a registered user a copy of the order will also now be available on their profile page. This is also the same page layout used when viewing any previous orders.

Administrator Dashboard

Checkout

The Administrator Dashboard acts as a central hub for site administrators to manage the site. The dashboard page features a chart that shows the value of sales over the past 30 days. I used a JS library to achieve this and display it in a canvas element. Here you are also able to see the last 10 database logs with icons that indicate whether it was an edit, delete, add or just general information.

Just below the heading section, four cards are indicating some site information.

Here you can see:

  • The current number of registered site users.
  • The total amount of games currently in the database.
  • The number of orders to date.
  • The total value of all sales.

These are also links to the relevant management views, these links can also be found in the management dropdown in the main nav-bar.

User Management

Checkout

In this section of the admin dashboard, site admins can see all currently registered users. Administrators can search for users by name using the search bar at the top of the table to filter the list. From this view you can see the username, date last seen and you can delete users by selecting the trash can to the right of the user you would like to delete. I have disabled the delete functionality in this view for site admins to avoid accidental deletions.

Game Management

Checkout

The game management page allows the admin user to manage the current games in the database. This view also features a search bar for filtering game titles. Game is listed in a table with an edit button to the left of each row for easy game editing and deletes button to the right to delete the game from the database.

On the top left of the table, there is an add button where an admin can add a new game to the database.

Add or Edit Game

Checkout

Adding or editing a game is done in the the same way. Administrators are presented with the form view pictured above. Here they are able to fill in or edit game details. Games marked with the featured checkmark or discounted checkmark will be added to the home pages and may be randomly selected to be featured on the main page slider.

upload

I am using Cloudinary(https://cloudinary.com/) ad my CDN to manage the sites media. For this site, I have implemented their media upload widget as it is a very powerful javascript tool. I have set the tool up to resize any images to the correct size for the website.

Error handling

404

I have implemented custom error pages to keep with the site theme, images are from Drlinkcheck.

Code structure

Below is an outline of the file and folder structure of the project as a whole. I have tried to keep things as organised as possible although the number of files is overwhelming at times.

.
├── cart
│   ├── apps.py
│   ├── contexts.py
│   ├── __init__.py
│   ├── migrations
│   ├── templates
│   │   └── cart
│   │       └── cart.html
│   ├── tests
│   │   ├── __init__.py
│   │   └── test_views.py
│   ├── urls.py
│   └── views.py
├── checkout
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0006_order_user_profile.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── signals.py
│   ├── static
│   │   └── checkout
│   │       ├── css
│   │       │   └── checkout.css
│   │       └── js
│   │           └── stripe_elements.js
│   ├── templates
│   │   └── checkout
│   │       ├── checkout.html
│   │       ├── checkout_success.html
│   │       └── confirmation_emails
│   │           ├── confirmation_body.txt
│   │           └── confirmation_subject.txt
│   ├── tests
│   │   ├── __init__.py
│   │   ├── test_forms.py
│   │   ├── test_models.py
│   │   └── test_views.py
│   ├── urls.py
│   ├── views.py
│   ├── webhook_handler.py
│   └── webhooks.py
├── custom_storages.py
├── dashboard
│   ├── apps.py
│   ├── forms.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── static
│   │   └── dashboard
│   │       ├── css
│   │       │   └── dashboard.css
│   │       └── js
│   │           ├── cloudinary.js
│   │           └── dashboard.js
│   ├── templates
│   │   ├── dashboard
│   │   │   ├── add_game.html
│   │   │   ├── dashboard_base.html
│   │   │   ├── dashboard.html
│   │   │   ├── edit_game.html
│   │   │   ├── games_management.html
│   │   │   ├── order_management.html
│   │   │   ├── order_view.html
│   │   │   └── user_management.html
│   │   └── includes
│   │       ├── dashboard_nav.html
│   │       └── info_tiles.html
│   ├── tests
│   │   ├── __init__.py
│   │   ├── test_forms.py
│   │   └── test_views.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── games
│   ├── admin.py
│   ├── apps.py
│   ├── fixtures
│   │   ├── categories.json
│   │   ├── games.json
│   │   ├── genres.json
│   │   └── tags.json
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0025_game_price_discounted.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── games
│   │       └── js
│   │           └── games.js
│   ├── templates
│   │   ├── games
│   │   │   ├── game_detail.html
│   │   │   └── games.html
│   │   └── includes
│   │       └── sort_dropdown.html
│   ├── tests
│   │   ├── __init__.py
│   │   ├── test_models.py
│   │   └── test_views.py
│   ├── urls.py
│   └── views.py
├── home
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── static
│   │   └── home
│   │       ├── css
│   │       │   ├── flickity.css
│   │       │   └── home.css
│   │       └── js
│   │           ├── flickity.pkgd.min.js
│   │           └── home.js
│   ├── templates
│   │   └── home
│   │       └── index.html
│   ├── tests
│   │   ├── __init__.py
│   │   └── test_views.py
│   ├── urls.py
│   └── views.py
├── htmlcov
│   ├── coverage_html.js
│   ├── index.html
│   ├── status.json
│   └── style.css
├── manage.py
├── media
│   └── header.jpg
├── Procfile
├── profiles
│   ├── apps.py
│   ├── forms.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── profiles
│   │       └── css
│   │           └── profile.css
│   ├── templates
│   │   └── profiles
│   │       └── profile.html
│   ├── tests
│   │   ├── __init__.py
│   │   ├── test_forms.py
│   │   ├── test_models.py
│   │   └── test_views.py
│   ├── urls.py
│   └── views.py
├── README.md
├── requirements.txt
├── static
│   ├── css
│   │   ├── all_auth.css
│   │   └── base.css
│   ├── images
│   │   ├── turn-games-full-logo.webp
│   │   ├── turn-games-logo.svg
│   │   ├── turn-games-text.png
│   │   └── turn-games-text.webp
│   └── js
│       └── base.js
├── templates
│   ├── 404.html
│   ├── 500.html
│   ├── allauth
│   │   ├── account
│   │   │   ├── account_inactive.html
│   │   │   ├── base.html
│   │   │   ├── email
│   │   │   │   ├── email_confirmation_message.txt
│   │   │   │   ├── email_confirmation_signup_message.txt
│   │   │   │   ├── email_confirmation_signup_subject.txt
│   │   │   │   ├── email_confirmation_subject.txt
│   │   │   │   ├── password_reset_key_message.txt
│   │   │   │   └── password_reset_key_subject.txt
│   │   │   ├── email_confirm.html
│   │   │   ├── email.html
│   │   │   ├── login.html
│   │   │   ├── logout.html
│   │   │   ├── messages
│   │   │   │   ├── cannot_delete_primary_email.txt
│   │   │   │   ├── email_confirmation_sent.txt
│   │   │   │   ├── email_confirmed.txt
│   │   │   │   ├── email_deleted.txt
│   │   │   │   ├── logged_in.txt
│   │   │   │   ├── logged_out.txt
│   │   │   │   ├── password_changed.txt
│   │   │   │   ├── password_set.txt
│   │   │   │   ├── primary_email_set.txt
│   │   │   │   └── unverified_primary_email.txt
│   │   │   ├── password_change.html
│   │   │   ├── password_reset_done.html
│   │   │   ├── password_reset_from_key_done.html
│   │   │   ├── password_reset_from_key.html
│   │   │   ├── password_reset.html
│   │   │   ├── password_set.html
│   │   │   ├── signup_closed.html
│   │   │   ├── signup.html
│   │   │   ├── snippets
│   │   │   │   └── already_logged_in.html
│   │   │   ├── verification_sent.html
│   │   │   └── verified_email_required.html
│   │   ├── base.html
│   │   └── socialaccount
│   │       ├── authentication_error.html
│   │       ├── base.html
│   │       ├── connections.html
│   │       ├── login_cancelled.html
│   │       ├── messages
│   │       │   ├── account_connected_other.txt
│   │       │   ├── account_connected.txt
│   │       │   ├── account_connected_updated.txt
│   │       │   └── account_disconnected.txt
│   │       ├── signup.html
│   │       └── snippets
│   │           ├── login_extra.html
│   │           └── provider_list.html
│   ├── base.html
│   └── includes
│       ├── footer.html
│       ├── main-nav.html
│       ├── messages
│       │   ├── message_error.html
│       │   ├── message_info.html
│       │   ├── message_success.html
│       │   └── message_warning.html
│       └── messages.html
└── turn_games
    ├── asgi.py
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

90 directories, 398 files

Stripe Payments

stripe

Using Stripe I was able to implement a payment system, the above image shows the successful transaction history.

Features Left to Implement

This project was a lot of fun and there are just so many features I would like to have implemented but ran short on time, I listed some of the key features below.

  • setting up cards to all fave a fixed max size
  • more work on rating system and user profile areas
  • avatars for user profiles
  • more charts and greater control of content in the admin dashboard
  • printing of order forms

Contents


Technologies Used

The following is a list of tools and technologies I used to create this website:

  • Python 3.8.3
    • Used for backend data manipulation
  • Django 3.1.1
    • Used as main python framework
  • Jinja2 2.11.2
    • Used as the main templating language for template manipulation
  • Cloudinary 1.21.0
    • Used to access the Cloudinary CDN server for image management
  • HTML5
    • Used as the main language for the templates
  • CSS3
    • Used for styling the webpage
  • JavaScript
    • Used for some front end functionality
  • Git
    • Used for version control
  • Google fonts
    • Used for website fonts
  • Font Awesome
    • Used for some icons on the website
  • Heroku
    • Used to host the website
  • GitHub
    • Used to store my project source code
  • Bulma
    • Used as the sites main css framework
  • Flickety
    • Used to create the main slider on the homepage
  • Stripe
    • Used for secure credit card payments
  • Kaggel
    • Used to get some data for the site

Other Tools

  • Pycharm
    • This is the main IDE I used to build the website.
  • Pixlr
    • Used to manipulate and create content for the website.
  • Grammarly
    • Used to double-check all my spelling and grammar.
  • W3C Markup
    • Used this to check my HTML for errors and typos.
  • W3C CSS
    • Used this to check the validity of my CSS.
  • jshint
    • Used to validate JavaScript.
  • black
    • Used for formatting python code.
  • Autoprefixer
    • I used this tool to make sure I did not miss any prefixing in my code.

Contents


Testing

Testing and error checking was undertaken throughout the development process. With the aid of the following tools and the help of human testers, I was able to catch and fix errors and bugs in my code.

Even though using this validator would understandably show errors for the jinja code I managed to catch some small mistakes by validating all the individual Html files.

I tested all the CSS files in the project using W3C CSS validator with no errors as per the image below.

After finishing up my CSS and before the validation of CSS I used this tool to make sure I had not left out any prefixing in my code.

Unit Testing

testing

Coverage

With the use of Django unit tests and coverage I created tests for my codebase, interestingly I discovered some bugs when implementing the tests that I believe I would have otherwise missed.

Google Lighthouse

lighthouse

Using the development tools inside chrome and google lighthouse I was able to fix some of my sites performance issues.

Browser and Device Testing

Browser Device Compatibility Version Notes
Google Chrome Desktop ★★★★★ Version 85.0.4183.121
Firefox Desktop ★★★★★ Version 81.0
Edge Desktop ★★★★★ Version 85.0.564.63
Samsung Internet Galaxy S8 ★★★★★ Version 12.1.2.5
Safari iPhone 8 ★★★★☆ Version 14.0 Some small styling differences & google sign in incompatibility
  • Test links to all pages
  • Test errors by typing in random page redirects
  • Try to access the user area without signing in
  • Test filtering dropdowns
  • Test searching
  • Test clearing search
  • Test card links
  • Test social links
  • Test ratings
  • Test adding and removing items from cart
  • Test checkout process
  • Test user login
  • Test editing user profile
  • Test dashboard view
  • Test add game
  • Test edit game
  • Test delete game
  • Test add featured and discounted game

User Testing

This was probably the most useful of all, I had several friends and family test the application. This helped me get feedback and find bugs I had missed. Some included styling issues on different devices to some UX ideas to make it a bit more intuitive. Unfortunately, I could not implement all the suggested features in time but the feedback was invaluable. Below are some of the feedback images I received and consequently fixed.

error error error error error

Contents


Deployment

The Deployment of this site uses the following web technology therefore you will need the appropriate accounts:

  • GitHub - For hosting this site's Repository
  • Heroku - To host the website
  • Postgresql - To host the database though addon in Heroku
  • AWS S3 - Storage for the sites static files
  • Cloudinary - For hosting the websites images.
  • Stripe - For the payment system.

Prerequisites

To contribute to this repository you will need to have the following installed:

Development

There are several steps required to deploy a local version of this project.

Cloning

code

  • At the top of the repository click on the Code button as shown above.
  • Copy the path to the repo https://github.com/Frozenaught/turn-games.git.
  • In your command-line, navigate to the folder where you would like to make a copy of this repository ie: c:\MyRepos> or ~/Documents ❯ .
  • Type the following to clone the repo c:\MyRepos> git clone https://github.com/Frozenaught/turn-games.git or ~/Documents ❯ git clone https://github.com/Frozenaught/turn-games.git
  • Now you can navigate to the newly created directory c:\MyRepos\turn-game> or ~/Documents/turn-games ❯
Requirements.txt

Next, you will need to install all the projects dependencies type pip install -r requirements.txt or pip3 install -r requirements.txt. If you add or update any packages in the project or add any new ones then use pip freeze --local > requirements.txt to update the requirements.txt file with the new dependencies.

Environment Variables

You will need to set up the following environment variables on your system.

Variable name Used for Notes
EMAIL_HOST_USER Sending notification emails Can be created under the security tab inside a Gmail account
EMAIL_HOST_PASSWORD Sending notification emails Can be created under the security tab inside a Gmail account
STRIPE_PUBLIC_KEY Needed for the stripe payment system Can be created under the developer tab on your stripe dashboard
STRIPE_SECRET_KEY Needed for the stripe payment system Can be created under the developer tab on your stripe dashboard
STRIPE_WH_SECRET Needed for the stripe payment system Can be created under the developer tab on your stripe dashboard
AWS_ACCESS_KEY_ID Needed for the S3 Bucket static files available when creating the S3 bucket
AWS_SECRET_ACCESS_KEY Needed for the S3 Bucket static files available when creating the S3 bucket
AWS Deployment only - to tell Django to use s3 instead of local static files Should be used in the deployment and set to True
DATABASE_URL Deployment only - sets hosted Postgres database Found in Heroku under resources/ Heroku Postgres / Settings
SECRET_KEY used by Django as a salt to generate hashes can easily be generated here
Contribution
  • If you choose to make changes to the website I would recommend using separate branches so that you can go back to the original master branch if the changes don't work as expected.
  • Use git checkout -b <brancname> to create a new branch and edit the files accordingly.
  • If you are happy with the changes to use git commit -m "my commit message of changes I have made" to commit the changes.
  • Use git push to push the changes to the repository.
  • As these changes are on a different branch they will not be available on the deployed site until you merge them to the master branch.
  • To merge the new branch to the master branch switch to the new branch on GitHub using the branch selector dropdown menu.
  • create a new pull request and state what changes were made in the comment section.
  • submit the pull request and switch back to the master branch.
  • now I will have the option to merge the pull request and you will be done.
Site Deployment

code

The easiest way to deploy the project to Heroku is to set your connect method to GitHub and link the repository master branch. If you set the project up for automatic deploys it will deploy once the master branch is updated.

Contents


Credits

The bulk of the credits should go to the documentation of the various technologist I used and of course to the excellent course content provided by the Code Institute.

Content

The content on the site all comes from this dataset that was found on Kaggle, I had to clean it up and take only what I needed to allow fixtures to easily load the data into my models. I created this fixture_scripts folder with some python scripts to achieve this, it will only work for this purpose but it can be adapted for any dataset with a bit more time. Executing main_csv_to_django will create the fixture files. I used this repo as a guide on what I was trying to achieve.

Media

Images

  • All the images used on the site were extracted from the Kaggle dataset.

  • The logo was created by me using pixlr editor and gimp.

  • Error Images - Drlinkcheck

Acknowledgements

Along the development process, I saved all references I used to the References area in my Trello Board

Inspiration

Code

Contents

About

My final milestone project for my Code Institute course.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published