Cocktail Hour is a virtual recipe collection specifically designed for cocktail recipes.
It is a community based experience that allows casual, one-time users to browse recipes, and allows returning users to create profiles and upload and manage recipes.
You can find the live site here
- I want to be able to view recipes without having to register and account.
- I want to be able to search for specific recipes.
- I want to be able to search for recipes that have a specific ingredient.
- I want to have a varied range of cocktails.
- I want to have a some cocktail suggestions when I'm not sure what to look for.
- I want to have the option to register an account if I want to come back at a later date.
- I want to be able to log into my account.
- I want to be able to upload a recipe.
- I want to be able to add a recipe to the pre-determined collections.
- I want to have ease of access to any recipes that I have already uploaded.
- I want to be able to edit or delete any recipes that I have already uploaded.
- I want to be able to add new collections to the site.
- I want the new collection to be added to the appropriate site areas.
- I want to be able to edit the pre-existing collections.
- I want to be able to delete any collections.
For this project I wanted to have a dark feel to emulate a night-time setting. While there are some family-friendly recipes to choose from, the majority of the content will be more adult-themed so I feel that the bar-type setting was the way to go. In keeping with the bar theme, I decided to have a neon effect following throughout all pages.
Because the overall theme is dark, I wanted to go with accent colours that would pop in comparison. I found the perfect colour scheme in a Shutterstock article that would work with my idea, just with a couple of changes for contrast reasons.
There were two fonts that I was interested in for the site.
Neon Tubes by guxjohn fit perfectly with the neon light theme but is something to be used sparingly - I want to keep this just just headings and accents. I think too much of this would become tacky very quickly.
Raleway is the chosen font for the majority of the text. In comparison to Neon Tubes, it is quite simple and offers a contrasting elegance.
Imagery is an important part of the user experience. Any user that uploads recipes has to accompany it with an image. And when browsing the recipes and collections, this image is the main selling point of the recipe so it's the prominent feature of the recipe card.
Another visual element is the banners on the recipe and collections pages. One some of them, a cocktail image was best. But for others, a visual element that evoked a feeling was more appropriate. If this site were going into full production, the site owner/admin would be in charge of this.
Lastly is the neon effect. It ties into the nightlife theme so well and I decided to use it across all pages. I think doing this makes the site visually cohesive throughout.
All Wireframes were designed for laptop/computer, iPad/tablet and phone display.
- All wireframes here
- All designs here
The navigation menu will help the user move easily across all pages. For the collections pages, there is a dropdown menu in which all of those pages are held. This stops the navigation from becoming too cluttered.
The navigation buttons update depending on whether a user is logged in, and whether that user is the admin:
Nav Link | Not logged in | Logged in as user | Logged in as admin |
---|---|---|---|
Logo(back to home) | âś… | âś… | âś… |
Recipes | âś… | âś… | âś… |
Collections | âś… | âś… | âś… |
Manage Collections | ❌ | ❌ | ✅ |
Account | ❌ | ✅ | ✅ |
Log Out | ❌ | ✅ | ✅ |
Register | ✅ | ❌ | ❌ |
Log In | ✅ | ❌ | ❌ |
The carousel will allow the user to browse through the different recipe collections. This adds a more visual element rather than the simple text of the collections dropdown on the nav bar. All of the carousel images will link the user to the collection page of their choosing.
As someone who doesn't particularly like to sign up to websites that I don't plan on adding to but like to view, I wanted to make all of the recipes accessible to a casual viewer. The user can also browse through all of the collections without having to have an account. But in order to interact with the site, they Do have to have an account. Without one, the option to upload anything isn't available.
Searching by ingredient is an important feature for any recipe website so that was something that I wanted to include. But people who are familiar with cocktails in general might be looking for a specific recipe based on name so this was also included in the search criteria.
At the moment, the database is relatively small. But if this were site that was going into full production, the recipes list would be much more extensive. As a result, the number of recipes displyed to the user could become overwhelming very quickly. I've limited to number of recipes to 12 per page - there's still a good amount displayed to the user without being too much. This will also help reduce loading times, especially on mobile devices.
While the 12-per-page layout mentioned above is quite condensed on a laptop or computer screen, it still comes across as quite lengthy on small mobile devices. During manual testing, I found it tedious to have to keep scrolling back to the top. Because of this, I added a scroll-to-top button on any pages that display recipe. This will save endless scrolling for the user.
Another issue that I found was once I had selected a recipe to view in full, it felt like a bit of a dead end. I decided to add a 'Back to Recipes' button at the top of the page. It just redirects back to the previous page much like the back button but from a UX POV it feels less breakable!
Anyone is able to make an account through the 'Register' page. They have to choose a username and a password. Measures have been put in place so that the user cannot choose a username that is already taken and they cannot use just whitespace.
Once their account is made, they will be able to log in an out when needed.
A registered user is able to upload recipes to the site. Once they have recipes that they have added, all recipe management can be done from their account page. This includes editing a deleting. I decided to keep these features exclusive to the account page rather than accessible on the recipes or collections pages. I like the uniformity of this.
-
Uploading: when uploading, there are form validations in place that the user needs to adhere to. The two most important are:
- The user cannot leave any inputs blank
- The user cannot use just whitespace.
-
Editing: the user will have to go into the edit page through the recipe, make the necessary changes and confirm them at the bottom of the page. The user also has the option to cancel all changes. These steps assure that the user cannot do any of this by mistake.
-
Deleting: there is a confirmation modal in place to assure the user doesn't accidentally delete the recipe.
When uploading a recipe, the user needs to add an image alongside the recipe information. This image will be used on both the recipe card and on the full recipe page. But because the image is added via a url, there are some people who wither don't was to go to the rounds of finding one, or they simply can't on their device. iOS doesn't allow the user to copy an image url in the same way most android do. Because of that I have added a placeholder image url that the user can use in place of their own. It's a stylish image that was found on Unsplash that looks good with the overall feel of the site.
When uploading a recipe, the user is required to add their recipe to at least one collection. This allows the user to feel like they're adding to the community in a more thoughtful way. This also takes the responsibility of curating the collections off the owner/admin.
Only the admin can manage the collections pages. This includes adding, editing and deleting. The site has been designed so that the admin only has to use the collections management page to create a new collection at this will automatically be updated on the carousel, nav bar dropdown and the actual page will be created dynamically. Any edits or deletions to collections will also apply to those elements.
- A rating system that allows users to rate each others recipes.
- This could lead to sorting by top-rated recipes.
- Ability to 'save' recipes to a users own account to refer back to.
- Ability to upload a saved image to their recipe rather than relying on a URL.
- Users ability to update username.
- Users ability to delete their account.
- This could allow the user to either leave their recipes on the site or delete them along with the account
- Admin controlled 'featured' recipes
Below is the schema for my database:
Key | Value type | Desc |
---|---|---|
_id | ObjectId | |
category_name | string | used in recipes array |
carousel_img | string | url for the carousel image |
banner_img | string | url for the banner image |
While the category_name
key was planned ahead of time, I added the carousel_img
and page_url
keys later when I was experimenting with the carousel on the home page. The page_url
has since been removed but I've documented this in the Bugs and Fixes section of the testing.md file. The banner_img
was also a later addition.
Key | Value type | Desc |
---|---|---|
_id | ObjectId | |
category_name | array | each collection chosen by user from categories |
cocktail_name | string | |
main_ingredient | string | |
ingredients | array | individual ingredients input by user |
method | array | individual steps input by user |
image_url | string | |
created_by | ObjectId | object id taken from users |
User | Value type | Desc |
---|---|---|
_id | ObjectId | used in recipes |
username | string | |
password | string | hashed password for user security |
- Flask
- Flask-PyMongo
- Pip3
- dnspython
- jQuery
- Flask Paginate
- Jinja
- Werkzeug
- Materialize
- FontAwesome
- Google Fonts
- Heroku used to deploy live site
- MongoDB used to host database information.
- GitHub used to host repository.
- GitPod used to develop project and organise version
- Procreate used to design initial mock ups, tilable background, logo and other design accents.
- Adobe Photoshop used to cut and re-frame site images.
- Balsamiq used to create wireframes.
- RandomKeygen used to create a strong password for required
<SECRET_KEY>
. - CloudConvert to convert all images to .webp format.
- Autoprefixer CSS used to make CSS cross-browser compatible.
- Transfonter used to convert font from .tff to .woff and .woff2.
- Lighthouse for performance review.
- PowerMapper used to check compatibility with older browsers.
- Responsinator used to check site was responsive on different screen sizes.
- Am I Responsive used to generate README intro image.
- Autoprefixer used to make CSS cross-browser compatible.
- favicon.io used to create a site favicon.
- Imgur used to host images.
Due to the size of the testing section, I have created a separate document for it. You can find it here.
This project was deployed through Heroku using the following steps:
Heroku needs to know which technologies are being used and any requirements, so I created files to let it know. Before creating the Heroku app, create these files using the following steps in GitPod:
- In the GitPod terminal, type
pip3 freeze --local > requirements.txt
to create your requirements file. - In the GitPod terminal, type
echo web: python run.py > Procfile
to create your Procfile. - The Procfile needs to contain the following line:
web: python app.py
and make sure there is no additional blank line after it. - Push these files to your repository.
Create and env.py file using the following information:
import os
os.environ.setdefault("IP", "0.0.0.0")
os.environ.setdefault("PORT", "5000")
os.environ.setdefault("SECRET_KEY", " *unique secret key* ")
os.environ.setdefault("MONGO_URI", " *unique uri from mongo.db * ")
os.environ.setdefault("MONGO_DB", " *database name* ")
Because this contains sensitive information, this needs to be added to the '.gitignore' file.
- Log into Heroku
- Select 'Create New App' from your dashboard
- Choose an app name (if there has been an app made with that name, you will be informed and will need to choose an alternative)
- Select the appropriate region based on your location
- Click 'Create App'
- From the dashboard, click the 'Deploy' tab towards the top of the screen
- From here, locate 'Deployment Method' and choose 'GitHub'
- From the search bar newly appeared, locate your repository by name
- When you have located the correct repository, click 'Connect'
- DO NOT CLICK 'ENABLE AUTOMATIC DEPLOYMENT': This can cause unexpected errors before configuration. We'll come back to this
- Click the 'Settings' tab towards the top of the page
- Locate the 'Config Vars' and click 'Reveal Config Vars'
- Use the following keys and values which must match the key/value pairs in your env.py file:
Key | Value |
---|---|
IP | 0.0.0.0 |
PORT | 5000 |
SECRET_KEY | Secure secret key |
MONGO_URI | mongodb+srv://root:PASSWORD@myfirstcluster.dr4g1.mongodb.net/cocktail_hour?retryWrites=true&w=majority |
MONGO_DBNAME | cocktail_hour |
- Go back to the 'Deploy' tab and you can now click 'Enable Automatic Deployment'
- Underneath, locate 'Manual Deploy'; choose the master branch and click 'Deploy Branch'
- Once the app is built (it may take a few minutes), click 'Open App' from the top of the page
- Log in to GitHub and locate the GitHub Repository
- At the top of the Repository above the "Settings" Button on the menu, locate the "Fork" Button.
- You will have a copy of the original repository in your GitHub account.
- You will now be able to make changes to the new version and keep the original safe.
- Log into GitHub.
- Locate the repository.
- Click the 'Code' dropdown above the file list.
- Copy the URL for the repository.
- Open Git Bash on your device.
- Change the current working directory to the location where you want the cloned directory.
- Type
git clone
in the CLI and then paste the URL you copied earlier. This is what it should look like:$ git clone https://github.com/AmyOShea/MS3-Cocktail-Hour
- Press Enter to create your local clone.
NB: In order to work with a clone of this project, you will need to create the env.py file using your own variables and create a MongoDB database matching the one documented in the Database section of this doc.
You will also need to install all of the packages listed in the requirements file you can use the following command in the terminal pip install -r requirements.txt
which will do it for you.
-
REGEX pattern for form input validation taken from this Stack Overflow post.
-
The HTML back button was taken from this W3Schools page.
-
I used this Stack Overflow post to adjust the placement of the nav bar dropdown.
-
This code for materialize slider autoplay was taken directly (also credited in in js file).
-
My own neon text css classes taken from this article and re-worked for my neon boxes (also credited in in css file).
-
This demo was used to understand how to incorperate flask pagination into my pre existing code.
-
This Stack Overflow post helped me gain more of an understanding of pagination offset.
-
This Stack Overflow post helped with the Pylint warning that I was getting and provided the comment to override it.
-
I used the code in this W3Schools post to create the scroll-to-top button.
-
I took the JS code from this Stack Overflow post for the carousel autoplay functionality.
-
Collections:
-
Pitchers Banner and Carousel image from Melbourne Cocktails
-
Shots Banner and Carousel image from Food For Net
- All test recipes that I added were collected from BBC Good Food website:
- All other recipes added by friends/family testers
- All the friends who tested the site, even in its earliest stages.
- Everyone in the CI Slack that offered answers, advice and just a bit of a chat when needed!
- My mentor Antonio Rodriguez for for his help at the different stages of the project.