Recycling Hive ♻️
♻️ Welcome to Recycling Hive! ♻️
Thanks for coming to take a look.
Recycling Hive is a place for community members to find out what they can recycle locally, and where. This allows the environmentally-conscious of us to recycle above and beyond what our local authority accepts.
Contents
✨ UX
📚 User Stories
🌍 Scope Plane
🌈 Surface Plane/Design Choices
📋 Wireframes
📀 Database Design
🔮 Future Developments
🚧 Development Process
🔓 Technologies Used
💻 External Sources Used
🐛 Bugs
🧹 Refactoring
🌳 Branches
🧪 Testing
🙋 Target-User Tests
🧑🤝🧑 Peer Tests
📝 Manual Tests
✔️ Online Validators
🚨 Lighthouse Tests
🛫 Deployment
🎬 Credits
🎥 Media
🏆 Acknowledgements
✨ UX
The idea for this project comes from a zero-waste/recycling community on Facebook that I am an active member of.
A large part of the group is built around dedicated individuals who collect a multitude of items that cannot be recycled via our local authority and arrange for these items to be sent to companies that do have the ability to recycle them. These individuals do this completely voluntarily and save incredible amounts of waste from going to landfill. Whilst I have co-ordinated collections myself in the past, I tend to be more of a waste-contributor than a waste-collector. So, I wanted to give something back to this amazing group by creating this site.
Currently, all the recycling locations for the group are stored in an Excel spreadsheet which has become very unwieldy as it grows and is hard to keep up-to-date. My hope in creating this site is that not only will this save the admin team a great deal of time, but will also make it easier for local community members to find out what they can recycle, and where.
My eventual aim for the site is to offer it to other similar groups across the UK so that more people can find a Hive close to them where they can save more rubbish from landfill.
Disclaimer: I think it is also important to point out here that recycling is not the answer, it is the last resort: 'rethink, repair, refuse, repurpose, reduce, re-use, recycle'. However, if something can be recycled, it should be recycled.
📚 User Stories
-
👩 Site Owner
- As a user I want a site that can be easily replicated for different Hives across the UK
- As a user I want minimal ongoing maintenance work - the majority should be undertaken by the Queen Bees (admin) of each Hive
-
🐝 Queen Bee
- As a user I want to be able to maintain the membership database, with full CRUD accessibility
- As a user I want to be notified when one of my Worker Bees adds or updates a recycling location
- As a user I want to have full CRUD accessibility over all recycling locations within my Hive
-
🐝 Worker Bee
- As a user I want to have full CRUD accessibility over the recycling locations that I add to the Hive
-
🐝 Busy Bee
- As a user I want to be able to easily find what items I can recycle locally, and where
- As a user I want to be able to make suggestions about items that can be recycled nationally
🌍 Scope Plane
- ➿ Site Logic
Membership types
Membership | Approval | Notes |
---|---|---|
SuperUser | N/A | The SU is the site owner - and the person responsible for the Mongo DB |
Queen Bees | First person to request a Hive location is given QB access | A current QB can request additional QBs (up to a max of 4 per Hive) to the SU |
QBs cannot be deleted. A request must be made to the SU to first demote them and the profile can then be kept (as WB or BB) or deleted entirely | ||
If a Hive has only one QB, they must find and approve another QB before they can be removed | ||
Worker Bee | Approved by QBs upon adding a new recycling location | Once WB status has been given, all future private locations are automatically approved |
Busy Bees | Approved by QBs on completion of registration | Each Hive will set their own security questions for registration so they can monitor new member requests |
Site access
Collection | QB Access | WB Access | BB Access |
---|---|---|---|
hives | ❌ | ❌ | ❌ |
hiveMembers | RUD for own Hive | CRUD for own profile | CRUD for own profile |
collectionLocations | RUD for own Hive | CRUD for own location(s) | R |
itemCollections | CRUD for own Hive | CRUD for own collection(s) | R |
publicCollections | CRU | CR | CR |
firstCollection | RUD for own Hive | ❌ | C |
itemCategory | CR | CR | CR |
recyclableItems | CR | CR | CR |
CRUD = Create, Read, Update, Delete
🌈 Surface Plane/Design Choices
✏️ Font families
I decided to go for a 'handwritten' style of font for the entirety of the site. I chose this as I felt it would contribute to the 'community noticeboard' feel I was aiming for.
🎨 Colour choices
I chose fairly typical colours for a site revolving around recycling and the environment, based on a recycling image that I particularly liked from here
The highlighted row is the main colour used throughout, with buttons and flash messages using varying shades of the same colour. Font colour was an off-black (#333) and in the vast majority of cases, was placed over an off-white (#fafafa) background for improved readability.
📋 Wireframes
The site was designed with a mobile-first approach.
Wireframe document can be seen here
💡 Deviation from wireframe
There was quite a lot of deviation from the original wireframe plan. This was mostly due to underestimating the complexity of the final database and also making better design decisions as my understanding/proficiency improved.
The majority of the deviation was in the form of creating entirely new pages for the site. Whereas pages that were originally planned for have mostly stayed true to the original concept.
I had also originally designed a lot of the content to be displayed in modals. As I began to delve more into Flask, I realised that additional pages (rather than modals) would be a much more preferable option!
Homepage
- The hexagon design on the homepage has been altered to be in-keeping with the rest of the site.
- I decided to include a link to the FAQs on this page to make them more accessible.
- Rather than requesting the site-visitor register in order to view the demo-site, I opted to make it instantly accessible to reach more potential members.
FAQs
- Very few deviations, except I had originally planned to have an image on this page. I eventually decided against it as I felt that an image would be at odds with the look of the rest of the site.
Register - Find a Hive
- This was in part a design choice, and in part due to prioritising other parts of the site. I had originally planned to have a searchable map using the Google Maps API.
However, I decided to stick with the hexagon layout to show the currently available Hives. This might be something I go back to in the future.
Register
- Have included a link to the login page for those that have already registered.
- Have included a link to the contact page for those that could not find a local hive.
Homepage - for logged-in users
- This page ended up with additional links to pages that hadn't been planned for:
- Add collection
- Contact
- Manage Hive (for Queen Bees)
- I also included a link to the FAQs to make them more accessible.
- The 'Be inspired' page and its link were removed altogether (as explained further down).
- I also decided to add a notification bar. This was following feedback from my first round of tests, as testers felt that communication within the site was lacking.
Profile
- This remained largely the same, except for the addition of another card to show public collections that had been added by the user
Hive
This has probably had the biggest overhaul from how it was originally envisaged.
In reality, it is the most important part of the site - its sole purpose really! And it was difficult to find a design that was visually-appealing, clear and comprehensible, and
that also worked well with the database design. I hope I have managed to meet all those goals in the end.
- The original 'Explore categories' page was used as the main design for all new pages.
- Rather than using cards and dropdowns as I had originally planned, I decided to split all the content into several new pages. This achieved:
- More visual appeal than using a table-design as shown in the wireframe
- A much clearer layout with fewer buttons and filters grouped onto a single page
- A better way to work with Flask as it allowed me to separate my functions into different routes for different pages
Add New Location - modal
This concept also went through several iterations before I was happy with how it worked. The original idea was to have two separate modals - one for adding private/personal collections and one for adding public collections. However, I was concerned that what seemed obvious to me (i.e. what type of collection it would be) might not be obvious to the user.
In the end, I have chosen to have a single page for adding all new collections. This page is then routed through radio buttons that hide/display relevant content via JS.
This means that the site does the work of deciding what goes where, rather than the user.
Be Inspired
This page was completely abandoned. Originally, it was going to be a place to display a randomly picked national collection, to inspire people to recycle something they hadn't thought of/ searched for. I was also going to give links to other sites that would be useful to people wanting to do more for the environment. However, I quickly realised that I had more than enough to be getting on with and so left this page for a future development.
Contact page
This page was added despite not being on the original wireframe as I wanted a way for site-users to be able to get in touch with me easily. And in particular, if new visitors wanted to set up a Hive, they needed a way to tell me!
Hive Management
My initial plan was for the Queen Bee(s) to do all of their admin within the original site pages. So, for each collection displayed on the main Hive pages, they would have access to edit/delete buttons to make any necessary amends. However, I soon realised that as the collections grow, it will get harder and harder to maintain without a central page for administration. Once I had decided to add this page, I used it as a place for all Queen Bee activity - accepting/deleting members, promoting to Worker Bee, accepting public collections...
📀 Database Design
I opted for a document-oriented NoSQL database (MongoDB) and spent a large part of my planning time designing the database.
I initially ended up with the following six collections:
However, as the site grew more complex, so did my database design. I ended up with eight collections:
The key changes were:
hives
- Added securityQuestion field so that each new Hive could set their own question for registration
hiveMembers
- Added fields to store registration responses to security and marketing questions
- Added approvedMember field to block parts of the site from the member until their registration has been approved
itemCategory/typeOfWaste
- Added _lower fields to both to allow for easier matching on newly added documents - to avoid duplication
collectionLocations
- Removed hiveID field as this is covered by the memberID
- Added nickname and nickname_lower fields to allow a member to store more than one location (e.g. Home/Work) and easily distinguish between the two
itemCollections
- Removed isNational field as this is now covered by the new 'publicCollections' collection
firstCollection
- This is a new, temporary collection for storage of the first collection a member adds.
Its purpose is to allow the Queen Bee(s) to check all information given, before committing it to the permanent 'itemCollections' collection.
By putting it in its own collection (rather than having a Boolean field in 'itemCollections' to indicate a first collection), there was less searching required to find relevant documents for Queen Bee approval on the Hive Management page.
publicCollections
- This is another new collection to store details of public collections. I felt putting these details in a separate collection (rather than using the 'isNational' Boolean field I had originally planned on), was a more straightforward approach as some of the data fields needed for this collection were slightly different.
In hindsight, I realise that using a NoSQL database for this website might not have been the ideal approach. However, it has given me a huge amount of experience using MongoDB, so all is not lost.
🔮 Future Developments
As this site is intended to be used by my local community, and potentially other communities in the future, there is a lot more that I would like to do with it.
At this stage, I have had to make some difficult decisions about when to stop working on it so that I can actually submit it.
It will definitely be an ongoing project and some ideas I am already thinking about are:
- Changing the 'Find a Hive' page to include a searchable map - if there are enough Hives set up to warrant this.
- Creating the 'Be Inspired' page to showcase alternatives to single-use products, and promote sites with a similar ethos
- Adding a forum/messaging system so that members of a Hive can communicate with each other
- Including additional information in the hive collection modals - for example, a telephone number/email address field for relevant cases
- Adding a search facility to find recyclable items more quickly
🚧 Development Process
🔓 Technologies Used
Languages
Libraries & Frameworks
Tools
💻 External Sources Used
-
Honeycomb background
- The effect for the header/footer was adapted from code taken from here
-
Hexagon grid layout
- This layout was adapted (with some difficulty!) from the code and tutorial on Codesmite.com
The adapted (but largely original) is within the hexagon.css file.
- This layout was adapted (with some difficulty!) from the code and tutorial on Codesmite.com
-
Email
- The JS required to send emails through the contact form was from EmailJS.com
-
Password validation
- The password validation JS was adapted from an explanation given on Stackoverflow.com
-
Favicon
- Generated using Favicon.io
🐛 Bugs
Bug 1
A main cause of issues during the creation of this project concerned the hexagon grid layout.
I didn't want to abandon the css entirely as I am overall very pleased with how it looks and how
it ties in with the overall theme of the sight, and so I had to find some workarounds in order for
it to behave as I needed.
The spacing on the hive-category page was one such issue, with the hexagon grid overlapping the
breadcrumb navbar at the top.
My workaround was to include a button as on the other pages (where spacing was not an issue), but
set the button's visibility to hidden.
Bug 2
Less of a bug, and more of a complex solution to an issue...
I was surprised to find that there was no easy solution to displaying text if a jinja 'for loop' was empty.
Essentially, on the hive members page, I wanted to display a list of all of the collections relevant to the selected member.
The 'for loop' worked perfectly to display their data, but for members without a collection, the list was blank. In this scenario I wanted
to display some text to signify to the user that this was not an error, but instead that there were no collections to display.
Initial working code
{% for collection in membersDict if collection._id == member._id %}
{% include "components/collection-details-modal.html" %}
{% endfor %}
This first piece of code displayed data, but no text for collection-less members.
First adjustment
{% for collection in membersDict %}
{% if collection._id == member._id %}
{% include "components/collection-details-modal.html" %}
{% else %}
<p>No collection to display</p>
{% endif %}
{% endfor %}
After the first adjustment, the data was displayed correctly for members with a collection. For members without a collection, the text was repeated by the total number of collections.
I tried many other solutions including variations of:
Second adjustment
{% if member._id in membersDict %}
{% for collection in membersDict if collection._id == member._id %}
{% include "components/collection-details-modal.html" %}
{% endfor %}
{% else %}
<p>No collection to display</p>
{% endif %}
But none of these worked as 'membersDict' is a nested list and so 'member._id' could not be found.
What appeared to be the perfect solution in Python:
Third adjustment
{% if (any(member._id in x for x in membersDict)) %}
{% for collection in membersDict if collection._id == member._id %}
{% include "components/collection-details-modal.html" %}
{% endfor %}
{% else %}
<p>No collection to display</p>
{% endif %}
Did not translate to Jinja and so this adjustment did nothing.
Solution
{% if member._id in membersCollectionValues %}
{% for collection in membersDict if collection._id == member._id %}
{% include "components/collection-details-modal.html" %}
{% endfor %}
{% else %}
<p>No collection to display</p>
{% endif %}
The only solution that I was able to find that worked, was to create a new un-nested list in my Flask route, which contained all the member IDs with collections. I was then able to search this list to enable my 'if statement'.
I am still not convinced that this is the most elegant solution, but it was the best I was able to come up with for this issue!
🧹 Refactoring
As my app.py file grew quite large and unwieldy, I needed to do some refactoring to ensure everything was in the right place, and to try and keep my code as DRY as possible.
To do this, I created a utilities.py file and moved any helper functions there.
For now, I have just done this for anywhere that there were large duplications of code. This has resulted in a reduction in the app.py file of 530 lines of code.
In future, I would make more use of a utilities file and ensure that only logic-based/routing code is kept in the app.py file.
A further improvement would be to reduce some of the repeated code in my various components. For example, tooltips and modals. However, I have decided against refactoring this as I am reluctant to undo too much of the work I have already done. This is something I will take forward into my next project.
🌳 Branches
The majority of the build was carried out in a Development branch with additional sub-branches being pulled through as work was completed.
Prior to testing, all working code was pulled through into the Master branch and amends from testing feedback have all been pulled directly into the Master branch from sub-branches.
🧪 Testing
Throughout the build, all functions were continually tested as new functionality was added. This was carried out with the help of Google Dev Tools to ensure that new features worked and displayed as expected on mobile, tablet and desktop views.
Once the majority of the site was built, I turned to user testing. The user tests were designed to not only test aesthetics and functionality, but also the database and whether data was committed correctly.
🧑🤝🧑 Peer Tests
The first stage of external testing was carried out by my family.
They were given an explanation on how their data would be used within the site:
They each also had specific instructions relating to a user-story to ensure that all functions were fully tested.
Queen Bee instructions
Worker Bee instructions
Busy Bee instructions
Feedback from this was good with no suggestions for change from Jane or Chris.
Tom had some suggestions which are shown on the Testing Feedback document.
Having acted on the feedback from the Peer Tests I moved onto Target User Tests.
🙋 Target User Tests
These tests were conducted by volunteers from the Facebook group that inspired this project. In total, there were 6 testers.
They were given the same data explanation as the peer testers: Data explanation
Both Jenny and Hannah encountered an error message which was not picked up by the Python error handler. Fortunately, they screenshotted the error so I was able to confirm that it was caused by some work I was doing whilst they were testing. The error has not happened since.
Otherwise, feedback was very positive, with some suggestions for cosmetic/functional improvements:
The majority of the feedback was acted upon (highlighted in green on the document) and improvements were made to the site. All of the suggestions were very good, but time constraints have meant that I cannot implement all of them. Those that are not being put in place now, have been put in the Future Developments section of this README.
📝 Manual Tests
Manual testing was carried out on all devices available to me:
-
Google Dev Tools:
- Mobile device
- iPad vertical
- iPad horizontal
- Desktop
-
Published site:
- Samsung Galaxy S8
- Desktop
-
Browser
- Chrome
- Edge
- Firefox
- Safari (Using Lambdatest)
- Opera
All tests produced good results with the following exceptions:
-
Text breakpoints on smaller devices
- On mobile view in particular, the text within the hexagons on the 'Search Hive' pages breaks mid-word if a '/' is used.
Unfortunately, due to the nature of the data, it is likely that categories in particular will be set with a '/' to separate similar areas of recycling. There was no obvious solution to this problem so it is currently being left as a slight flaw.
- On mobile view in particular, the text within the hexagons on the 'Search Hive' pages breaks mid-word if a '/' is used.
-
Dropdown select on Firefox
- On Firefox, the dropdown select box does not use the site font; rather a font set by Firefox. To me, it isn't particularly aesthetically pleasing. But there doesn't seemed to be a way to remedy the problem and so it has been left as a minor issue.
-
Dropdown select on Safari
- The default display for dropdown select on Safari is not at all in keeping with the rest of the site. However, this is something that Safari users will presumably be used to.
The main issue is that the optgroup is shown as a dark grey on a black background, which is very annoying. I have tried many solutions in CSS to fix this issue, but it doesn't seem to have any effect. Regrettably, this is being left unsolved.
- The default display for dropdown select on Safari is not at all in keeping with the rest of the site. However, this is something that Safari users will presumably be used to.
Full testing-frame can be found here
✔️ Online Validators
JSHint
The script.js file was run through JSHint.com and produced no errors. email.js was not run through as it is an external source (see External Sources).
W3C CSS Validator
The style.css file was run through W3C CSS Validator and produced no errors.
hexagon.css was not run through as it is an external source (see External Sources).
W3C Markup Validation Service
Due to the use of Jinja2 across the site, it was not possible to copy the code from each internal file to use as direct input on the W3C Markup Validation Service.
Because the site is largely hidden from unregistered users, I also couldn't check via URI.
Therefore, I used the source code shown in Google Dev Tools for direct input.
Initially there were quite a few errors. The vast majority of these were from duplicate title-IDs within modals that were being looped through by Jinja2. These errors were all amended and no further errors remain.
🚨 Lighthouse Tests
The results of the Lighthouse Tests were generally good. Some minor amends were made to the code following the first round of tests:
- Moved tooltip text from div to anchor in footers for sr accessibility
- Added noreferrer to external links for improved security
- Added meta description
Accessibility required improvement on some pages:
- There were still some issues with the title text used in the footer links, despite it being there. No further amends were possible.
- Duplicate IDs were picked up in aria-labels, but I was unable to identify any duplicates and therefore could not make any improvements.
🛫 Deployment
Recycling Hive ♻️ was developed in Gitpod, hosted on GitHub and deployed to Heroku
Cloning Recycling Hive ♻️ from GitHub
You will need to recreate the database in MongoDB
The following instructions are for a Windows OS only. Please consult your OS for python commands.
- Clone the Recycling Hive ♻️ repository by downloading it from here, or if you have Git installed you can type the following into the CLI:
git clone https://github.com/jess-bennett/recycling-hive
- Within the new folder, type the following into the CLI:
python3 -m .venv venv
- And initialise the environment with:
.venv\Scripts\activate
- Install the necessary requirements from the requirements.txt file:
pip3 -r requirements.txt
- Create a file named 'env.py' with the structure below and replace the SECRET_KEY, MONGO_URI, MONGO_DBNAME and DEMO_ID* with your own values
import os
os.environ.setdefault("IP", "0.0.0.0")
os.environ.setdefault("PORT", "5000")
os.environ.setdefault("SECRET_KEY", "<your_secret_key>")
os.environ.setdefault("MONGO_URI", "<your_mongo_uri>")
os.environ.setdefault("MONGO_DBNAME", "<your_mongo_dbname>")
os.environ.setdefault("DEMO_ID", "<your_demo_id>")
*The Demo_ID should be the _id of a hiveMember using fictitious details
- The application can now be run using:
python3 app.py
Deploying Recycling Hive ♻️ to Heroku
- Create a requirements.txt file by typing the following into your CLI:
pip3 freeze > requirements.txt
-
Push to your repository, create a new app on the Heroku Dashboard
-
Change the deployment method to GitHub and ensure the app is connected and automatic deploys are enabled (if you wish)
-
In Settings, set the Config Vars as follows:
Key | Value |
---|---|
IP | 0.0.0.0 |
MONGO_DBNAME | <your_mongo_dbname> |
MONGO_URI | mongodb+srv://<your_username>:<your_password>@<your_cluster_name>. 6abok.mongodb.net/<your_database_name>?retryWrites=true&w=majority |
PORT | 5000 |
SECRET_KEY | <your_secret_key> |
DEMO_ID | <your_demo_id> |
- Deploy the app from the Heroku dashboard and open the app
🎬 Credits
🎥 Media
Images for Home Page navigation grid were taken from Font Awesome's SVGs
🏆 Acknowledgements
I would like to thank the following people for their help and support with this project:
♻️ Firstly, it has to be the entire 'Thatcham & Newbury plastic free, recycling & zero waste uk' Facebook group The work of the group members was the sole inspiration behind this project and the knowledge that is shared there is an inspiration!
♻️ Following this, I would like to thank the group moderators for their advice and support before starting this project: Jana Karstova Little, Jacky Akam, Jenny Kirby and Paula Smalley
♻️ With another special mention to the group members who kindly volunteered to help with testing - and went far above and beyond what I expected in terms of feedback: Hannah Marsh, Jenny Kirby, Jo Hands, Linda Mary, Merlin (Georgia!) Jackson and Nikki Coome
⭐ My husband, Tom - for being a very patient and encouraging site-tester and brain-storming partner. Also for endless hours at the park with Eddie so I could work!
⭐ My parents, Jane & Chris - for their patience and encouragement as site-testers.
⭐ Never forgetting my incredibly dedicated mentor, Simen. The tips and advice on improving my code are always appreciated!