- Project overview
- 1. UX
- 2. Features
- 3. Database Design
- 4. Technologies Used
- 5. Testing
- 6. Deployment
- 7. Credits
Are you passionate about Cryptocurrency? Crypto Connect is a free platform that allows you to connect with other like-minded professionals and learn about Cryptocurrency. Do you have any trading experience you'd like to share as well? Great news! You can create your own free account and start writing blog posts to share with the rest of the community! You can also connect and chat with other members in the community in our chat room!
The site is created to allow professionals to connect with others and learn about cryptocurrency, so is branded in a very simple classic design with white text on black background to ensure optimal legibility and minimal distraction.
I have used HTML, CSS, JavaScript and Python to build the site, ensuring it is fully responsive to user interaction on their chosen device.
The live website can be found at the following link; Crypto Connect.
This project is part of my Code Institute Full Stack Software Development studies, specifically the Backend Development module. The objective for this milestone project is to "*Create a web application that allows users to create user profiles and connect with other members, and to store and easily access blog posts, using the CRUD operations of Create, Read, Update, and Delete for their connections and blog posts.
I have decided to build a cryptocurrency networking project, since I personally have a strong passion for this new blockchain technology. I feel that there are too many scams out there and not enough reliable resources or a safe haven for beginners to enter the world of cryptocurrency. I would like to create a platform where people are able to connect with each other, so they can learn and share their experiences on not only the blockchain technology itself, but also trading advice and tips! Members in the community will be able to connect with each other, discuss their views in our chatroom or upload blog posts to share anything they feel passionate about cryptocurrency.
- As a user, I want the website to clearly display member’s profiles so I can be introduced to new members.
- As a user, I want the website to clearly display the blog posts to me so I can be introduced to the content.
- As a user, I want the website to clearly display all the messages in the chat room.
- As a user, I want to be able to search members by keyword, so I can find recipes easily, for example by name or location.
- As a user, I want to be able to make connections with other members on the platform from search results.
- As a user, I want to be able to upload my own blog posts, so other users can benefit from reading them.
- As a user, I want to be able to edit and improve posts I have already uploaded.
- As a user, I want to delete posts I have already uploaded.
- As a user, I want to be able to register with the site, so I can upload and edit my profile and blog posts.
- As a registered user, I want to be able to login to my account, so I can access and edit my profile, and to upload, edit or delete blog posts I created.
- As a registered user, I want to be able to make connections with other members and to remove them should I wish to.
- As a registered user, I want to communicate with other members on the platform.
-
As the site owner, I would like the site to be the “go-to” platform for users to learn and discuss cryptocurrency.
-
As the site owner, I would like to create a community for users in the blockchain technology / crypto market.
-
As the site owner,I would like to hear feedback from users to continuously improve user experience.
- As a user I want to receive clear feedback for my actions on the site, so I know they are complete or if further steps are needed.
- As a user I want to contact the admin should I wish to.
Overview of site and page structure, explaining functionality and purpose.
- Navigation Bar/Footer: For easy navigation across the site and to external resources such as social media pages.
- Website Logo: To easily identify the 'Crypto Connect’' site branding.
- Site Features: To easily provide users with an overview of the website’s features.
- Top Trading Coins Cards: To easily provide users with information about top trading cryptocurrencies.
- Sign Up Button: To allow users to easily access the registration page.
- Contact Form: To allow users to contact admin directly through a form.
- Search Bar: Text input bar, allowing users to search members by full name and location.
- Search Results: Once user search input, members are replaced by members cards matching the search query.
- Members Cards: To easily provide users key information on members in the community, including visual image, type of member, full name, birthday, location, job title, interests, experience and date joined.
- Connection Button: To allow users to connect with other members with easy access.
- Profile Card: To easily provide users key information of their own profile, including visual image, type of member, full name, birthday, location, job title, interests, experience and date joined.
- Update Profile Button: To allow users to edit their profile with easy access.
- Members Cards: To easily provide users key information on members they have connected with.
- View Profile Button: To allow users to be directed to a member's profile page for further information.
- Remove Connection Button: To allow users to remove connections with members they have connected with.
- Go to chat button: To allow users to be directed to the chat room to chat with other members in the community.
- Chat Message Box: Text input box, allowing users to write their message.
- Send Message button: To allow users to submit their message and have it displayed in the chatroom.
- Refresh Chat Button: To allow users to refresh the chat page to receive updated messages from the community.
- Add New Blog Post Button: To allow users to be directed to add_blog page to contribute to the blog by filling out a form.
- Blog Post Cards: To easily provide users key information on the blog post, including blog title, author and date published.
- View Post Button: To allow users to be directed to a specific blog post page to read the blog post.
- Edit Post Button: To allow users who created the blog post to be directed to edit_blog page to edit the post they contributed.
- Delete Button: To allow users who created the blog post to remove the blog post they contributed from the platform.
- Blog Post Image: Visual image uploaded by user/ default image for the blog post.
- Author: Display author of the blog post.
- Published date: Display the date of when the blog post was posted.
- Blog Content: Display content of the blog post.
- Username Input: Text input box, allowing users to enter their username.
- Password Input: Text input box, allowing users to enter their password.
- Sign In Button: To allow users to submit entered information, and if correct credentials will be directed to the profile page.
- Sign Up Button: To allow users to be directed to the registration page.
- First Name Input: Text input box, allowing users to enter their First Name.
- Last Name Input: Text input box, allowing users to enter their Last Name.
- Username Input: Text input box, allowing users to enter their username.
- Email Input: Text input box, allowing users to enter their email address.
- Password Input: Text input box, allowing users to enter their password.
- Sign Up Button: To allow users to submit entered information and register for an account.
At this point I began creating wireframes, using the above structure considerations. I used Balsamiq these below;
This is the sensory design section of a website, or how it looks, feels and sounds.
The logo comprises animated rings with a spaceship in the centre, along with the app name at the bottom. This gives a very eye-catching and clean aesthetic . The spaceship represents the dream of many crypto-investors - “Going to the Moon!”. This is the jackpot of cryptocurrency. It's when the price of a cryptocurrency skyrockets off the charts. It refers to a strong belief that certain cryptocurrency is soon going to rise significantly in price.
The site is created to allow professionals to connect with others and learn about cryptocurrency, so it is branded in a very simple classic design with white text on black background to ensure optimal legibility and minimal distraction. I chose to use a colour palette consisting of whites and black shades, with cadet blue and teal to highlight and for the hoovering effects.
The resulting palette is below;
- White - #fff
- Black - #111
- Black- #000
- Cadet blue- #5f9ea0
- Teal - #008080
I wanted the language to reflect a professional and educational atmosphere, whilst also reflecting a friendly and engaging style. Therefore content was written in this style, avoiding overloading of information or information that is too technical to understand.
Similarly, I wanted to use fonts that reinforce the identity of the site, to match the cryptocurrency theme and also be easy to read. To achieve this I used Google Fonts;
- Poppins - A geometric sans-serif typeface published by Indian Type Foundry in 2014.
- Sans-serif - Web safe font, used if primary font fails to load.
During the pre-development phase, I listed out some styling ideas that I thought would be beneficial to the website. Many of these can be found in wireframes.
- Font Awesome Icons : with hover effects to highlight key info
- Navigation
- Sticky top
- Mobile Side Nav: 'Burger' menu icon, expanding into side navbar on click
- Logo: Navigates to the index page on click
- Members Cards
- Visual Image showing member’s profiles
- Blog Post Banner / Image
- Visual Image to accompany blog content
The site allows users to register for an account. Users are able to login and logout of the site. They can create, upload and update their own profiles. Registered users are able to view other member’s profiles and make connections with them. Users can search for other members using their name or location. Users can see all the connections they have made in their profile page and remove existing connections at any time. Users are able to upload new blog posts, edit and delete existing ones that they have created.
Users can :
- Add their profile
- Edit their profile
- Add Connections
- Remove Connections
- Add blog posts
- Edit thier blog posts
- Delete their blog posts
- Website Logo: Builds brand awareness and identity amongst users.
- Navigation Bar: Enable users to navigate the site easily and intuitively, as well as login/register their account.
- Copyright: Copyright information for brand awareness.
- Social Links: Links to Social Media for brand awareness.
Both the Header and Footer are present and consistent on all website pages.
- Website Logo: Visually pleasing design, allowing users to immediately identify the site brand.
- Sign Up Button: Allows users to be directed to the registration page to sign up for an account.
- Site Features: Brief content showing site features.
- Top Trading Coins: Cards showing top trading coins with information about each one.
- Contact Form: Allows users to contact admin for feedback.
- Member Cards: Display other member’s key information, including visual image, type of member, full name, birthday, location, job title, interests, experience and date joined. Users are able to connect with other members via a click of a button. They are able to remove any connections at any time.
- Search Results: Once user search input, members are replaced by members cards matching the search query.
- Profile Card: Card showing relevant information on users profile, allowing users to quickly identify if they are using their desired account.
- Add Profile Button: To allow users to create their profile.
- Update Profile Button: To allow users to edit their profile with easy access.
- Members Cards: Display all the members’ profiles that the users have connected with. Option to remove connections at any time via a click of a button.
- Chat room: Users are able to chat with other members in the chat room.
- Input areas for below profile data points:
- Members type - Text
- Full name - Text
- Birthday - Date
- Location - Text
- Job Title - Text
- Experience - Text
- Interests - Text
- Profile Image - Url or default img
- Input areas for below profile data points:
- Members type - Text
- Full name - Text
- Birthday - Date
- Location - Text
- Job Title - Text
- Experience - Text
- Interests - Text
- Profile Image - Url or default img
- Blog Image: Default banner for blog posts or relevant image uploaded by author to accompany blog post.
- Blog Information: Display key information on the blog post, including blog title, author and date published.
- Blog Content: Display blog content.
- Submitted Blog Posts: Users are able to easily and quickly access to review, edit or delete blog posts they have created.
- Input areas for below Blog posts data points:
- Blog_Title - Text
- Blog Image - Url or default img
- Blog Content - Text
- Input areas for below blog post data points:
- Blog_Title - Text
- Blog Image - Url or default img
- Blog Content - Text
- First Name Input: Text input box, allowing users to enter their First Name.
- Last Name Input: Text input box, allowing users to enter their Last Name.
- Username Input: Text input box, allowing users to enter their username.
- Email Input: Text input box, allowing users to enter their email address.
- Password Input: Text input box, allowing users to enter their password.
- Sign Up Button: To allow users to submit entered information and register for an account.
As this is a community-focused platform, several future features would be worth considering implementation:
- Social Media Sharing - Allow users to share blog posts or their members' cards directly to their social media accounts.
- Advanced chat functionality - Allows users to private message individual members and receive notifications when they receive a message.
- Current Crypto Price Charts - Visual graphs to show users current prices of trending cryptocurrencies.
- User Comment Section - Allow users to comment on each other's blog posts, allowing constructive feedback and additional context to blog posts.
- Direct Image Upload - Embed image upload functonality to the site using Cloudinary.
- Optimised Image Delivery - Page load speeds could be sped up via using compression on user-uploaded images, to ensure they are srved in a fully optimised state. This could be done using Cloudinary to automatically compress images during upload.
- User Administration - Add user administration page, allowing admins to manage users accounts e.g. suspend accounts, set other users to admin etc.
- Advanced User Profile - Allow users to customize their own profile with custom information they wish to provide and share with other members.
MongoDB was the database solution used for the website development, using the below, structured plan.
Users Collection
Key | Type | Purpose |
---|---|---|
_id | ObjectId | ObjectId of this document |
firstname | String | stores the first name of the user |
lastname | String | stores the last name of the user |
username | String | stores the username of the user |
String | stores the email address of the user | |
password | String | stores the hashed password of the user |
connections | Array | stores the connections of the user |
date_created | String | stores the date the document was created |
Profiles Collection
Key | Type | Purpose |
---|---|---|
_id | ObjectId | ObjectId of this document |
member_type | String | stores the members type of the user |
fullname | String | stores the full name of the user |
birthday | String | stores the birthday of the user |
location | String | stores the location of the user |
job_title | String | stores the job title of the user |
interest | String | stores the interest of the user |
image | String | stores the image of the user |
created_by | String | stores the username who created the profile |
date_created | String | stores the date the document was created |
Blogs Collection
Key | Type | Purpose |
---|---|---|
_id | ObjectId | ObjectId of this document |
blog_title | String | stores the title of the blog post |
content | String | stores the content of the blog post |
image | String | stores the image of the blog post |
created_by | String | stores the username who created the blog post |
date_created | String | stores the date the document was created |
1. Text index on member’s full name and location, allowing for text searches.
mongo.db.profiles.create_index([
("profile_fullname", "text"),
("profile_location", "text"),
])
1. Find members:
list(
mongo.db.profiles.find({"$text": {"$search": search}})
)
1. Find a specific user account based on username:
mongo.db.users.find_one(
{"username": username}
)
2. Insert a new user record into the database, with a defined username, password and user role:
register = {
"username": request.form.get("username").lower(),
"password": generate_password_hash(request.form.get("password")),
"role": "user"
}
mongo.db.users.insert_one(register)
1. Add a new connection:
@app.route("/add_connection/<profile_id>", methods=["GET", "POST"])
def add_connection(profile_id):
if request.method == "POST":
user = mongo.db.users.find_one({"username": session["user"].lower()})
connections = mongo.db.users.find_one(user)["connections"]
# if member is already connected
if ObjectId(profile_id) in connections:
flash("You are already connected!")
return redirect(url_for("members"))
# otherwise adds member to users connections
mongo.db.users.update_one(
user, {"$push": {
"connections": ObjectId(profile_id)}})
2. Add a new blog post:
def add_blog():
if request.method == "POST":
# default values if fields are left blank
default_img = ("blog_image.png")
blog = {
"blog_title": request.form.get("blog_title"),
"content": request.form.get("content"),
"image": request.form.get("image") or default_img,
"created_by": session["user"],
"date_created": date.strftime("%d %b %Y"),
}
mongo.db.blogs.insert_one(blog)
3. Edit a blog post:
def edit_blog(blog_id):
if request.method == "POST":
# default values if fields are left blank
default_img = ("blog_image.png")
update = {
"blog_title": request.form.get("blog_title"),
"content": request.form.get("content"),
"image": request.form.get("image") or default_img,
"created_by": session["user"],
"date_created": date.strftime("%d %b %Y")
}
mongo.db.blogs.update({"_id": ObjectId(blog_id)}, update)
1. Delete a blog post:
def delete_blog(blog_id):
mongo.db.blogs.remove({"_id": ObjectId(blog_id)})
flash("Blog Post has been deleted")
2. Remove a connection:
@app.route("/remove_connection/<profile_id>", methods=["GET", "POST"])
def remove_connection(profile_id):
if request.method == "POST":
user = mongo.db.users.find_one({"username": session["user"].lower()})
mongo.db.users.update_one(user, {
"$pull": {"connections": ObjectId(profile_id)}})
- HTML - Programming language providing content and structure of the website.
- CSS - Programming language providing styling of the website.
- JavaScript - Programming language used for various interactive elements of the website, including game logic, audio options etc.
- Python - Programming language used to drive core site functionality including user login and push/retrieving database information.
- Jinja - Used to generate HTML from site templates
- Font Awesome - Library used for icons, such as social links and other images.
- Google Fonts - Font style library.
- jQuery - JavaScript library used for simplification of JS scripts and DOM manipulation.
- Flask - Micro-framework to simplify Python scripting and web server tasks.
- Werkzeug - Python library to manage user management integrity.
- Socket.IO - Used to create the chatroom functionality
- GitHub - Remote code repository.
- GitPod - IDE (Integrated Development Environment), for writing, editing and saving code.
- Balsamiq - Wireframes for visual design testing.
- Chrome DevTools - Chrome DevTools is a set of web developer tools built directly into the Google Chrome browser.
- Am I Responsive? - Responsive design demo in ReadMe summary.
- Responsive Design Checker - Check website response across device types.
- Heroku - Remote hosting platform, for hosting of python driven websites and applications.
The testing process can be seen in the TESTING.md document.
The site is hosted using Heroku, deployed directly from the master branch of GitHub. The deployed site will update automatically as new commits are pushed to the master branch.
-
From the Heroku dashboard:
- Select "New"
- Select "Create new app"
-
Add new app details to form:
- Add app name (must be unique)
- Select region
- Click "Create App"
-
From the Heroku dashboard:
- Select your app from the list
-
Select "Settings" from the top menu:
- Under 'Config Vars', select "Reveal Config Vars"
- Add environment variables in key-value pairs, click "Add" to add additional pairings.
-
Create required deployment files in the repository:
-
requirements.txt
- Lists the required python modules for Heroku to install.
- To create:
- In your IDE terminal, type:
pip freeze > requirements.txt
- In your IDE terminal, type:
-
Procfile
- Tell Heroku the command to launch the app.
- To create:
- in your IDE terminal, type:
python app.py > Procfile
- in your IDE terminal, type:
-
.gitignore (optional)
- Lists files and directories which should be deployed to live app, such as files with environmental passkeys.
- To create:
- In your IDE terminal, type:
touch .gitignore
- List the files and directories to be excluded from live deployment, within the .gitignore file.
- Save in your repository root directory.
- In your IDE terminal, type:
-
-
From the application top menu:
- Select 'Deploy'
- Choose your Deployment method:
-
Github:
- Select the correct Github account.
- Type in the repository name you wish to deploy.
- Choose the correct repository from search results.
- Select "Connect"
-
Manual Deployment:
- Choose the correct branch you wish to deploy from the drop-down.
- Select "Deploy Branch"
- Heroku will return "Your App has successfully deployed". If this shows an error, troubleshooting will be needed.
-
- From the application top menu:
- Select 'Deploy'
- Ensure app is connected to correct repository
- Under 'Automatic Deployment' section:
- Select 'Enable Automatic Deployment"
To run a version of the site locally, you can clone this repository using the following steps;
In a code editor of your choice;
- Go to GitHub.com
- Click on 'Repositories'.
- Click on 'Crypto Connect’.'
- Click on the 'Code' button.
- Under 'HTTPS' click the clipboard icon to the right of the URL.
- In your IDE of choice, open a repository or create a new repository.
- Open Terminal ('Terminal' then 'New Terminal' from the top ribbon menu in GitPod.)
- Type 'git clone', paste URL link and press enter.
Additional information around these cloning steps can be found on GitHub Pages Help Page.
- Install all requirements modules to your local IDE with the following CL:
pip3 install -r requirements.txt
-
Login to your MongoDB account
-
Create a Cluster
-
Create a database using the following architecture;
Users Collection
Key | Type | Purpose |
---|---|---|
_id | ObjectId | ObjectId of this document |
firstname | String | stores the first name of the user |
lastname | String | stores the last name of the user |
username | String | stores the username of the user |
String | stores the email address of the user | |
password | String | stores the hashed password of the user |
connections | Array | stores the connections of the user |
date_created | String | stores the date the document was created |
Profiles Collection
Key | Type | Purpose |
---|---|---|
_id | ObjectId | ObjectId of this document |
member_type | String | stores the members type of the user |
fullname | String | stores the full name of the user |
birthday | String | stores the birthday of the user |
location | String | stores the location of the user |
job_title | String | stores the job title of the user |
interest | String | stores the interest of the user |
image | String | stores the image of the user |
created_by | String | stores the username who created the profile |
date_created | String | stores the date the document was created |
Blogs Collection
Key | Type | Purpose |
---|---|---|
_id | ObjectId | ObjectId of this document |
blog_title | String | stores the title of the blog post |
content | String | stores the content of the blog post |
image | String | stores the image of the blog post |
created_by | String | stores the username who created the blog post |
date_created | String | stores the date the document was created |
- Create a '.gitignore' file in the root directoy
- Add 'env.py' and 'pycache/' to the file list within .gitignore
- Create a 'env.py' file
- In the 'env.py' file write the following code;
import os
os.environ.setdefault("IP", "0.0.0.0")
os.environ.setdefault("PORT", "5000")
os.environ.setdefault("SECRET_KEY", "[UNIQUE ID]")
os.environ.setdefault("MONGO_URI", "[UNIQUE ID]")
os.environ.setdefault("MONGO_DBNAME", "[UNIQUE ID]")
Note: For each sectionedn noted as [UNIQUE ID], you will need to provide your own unique identifier. These must also be aligned to Heroku environmental variables.
This is required when using flash() and session() functions in flask. The key can be of your own choice, but it's advisable to use a randomly generated secure key from websites such as RandomKeyGen.com.
This is used to connect you application to your MongoDB cluster.
-
Click 'Overview' tab from your Cluster, followed by 'Connect'.
-
Select 'Connect your application' from following window.
-
Select your correct version of Python and copy the connection string.
-
Replace the 'username' and 'password' text, with the relevant criteria you setup in 'Database Access'.
This is the name of your database in MongoDB. Which can be found under the 'Collections' tab, under your cluster.
This command is only available in Gitpod.
To launch a Http server using the development mode code for the application, use the following command in your IDE:
python3 app.py http.server
The IDE will then open a port with an http address for you to access.
- w3Schools -For checking proper syntax of HTML and CSS elements and codes for Profile Tabs functionality.
- Slack -Code function for flash messages.
- Autoprefixer - For generating CSS browser prefixes.
- Stackoverflow - For researching and troubleshooting JavaScript and Python code issues.
- MongoDB Documentation - For researching and troubleshooting database code commands and issues.
All text content on the site was written originally by myself, with the below notes;
- Top trending coins content were obtained from The 10 Most Popular Cryptocurrencies, and What You Should Know About Each Before You Invest.
The photos and images used for this site were obtained from :
- Thanks to my mentor, Tim Nelson for his encouragement and expert advise on the development of this project.
- Thanks to all the tutors on Code institue for thier constant support, time and patience.
- Thanks to those on the Slack community for answering my many questions 24:7!
- Thanks to my two sons - Chubby and Klaus, friends and family for the love and support, reviewing the app and offering constructive feedback.