Home EcoEarner
A development landing page and website of a start-up renewable energy company.

Tech Stack
- React JS
- Node JS
- Express
- Knex
- Sass
- Auth
- MySQL
- CoreUI
- MUI Icons
- API
Background
My father will be launching a renewable energy start-up company in the last quarter of 2023. I saw the opportunity to:
- Build on the design of an already existing landing page.
- Help integrate a database which would collect a users' name, email and postcode as they sign up to join the waiting list in advance of the company's launch.
- Add more pages such as a contact page which would contain a enquiry form as well as a news page which would list news articles that the company could write up.
- Present a way for an administrator to view all user details in a database provided on joining the waiting list, through the use of an admin page.
Screenshots





Challenges
Admin Authorisation
- It was tough to find the right way to ensure one admin user could log in to an admin database. But I found that I could store a username and password in an env file on the backend server and send this down to the client. When the admin enters the correct password, this would take them to the database.
- However, this wasn't a good user experience, as they would be logged out if they were to accidentally refresh the page. I ended up using a JWT token in local storage, which would give an admin the token when they entered the correct username and password. This means that a refresh wouldnt log them out of the page. I further added a log out button so they could securely log out, which in turn removes the token from local storage.
Dynamic Filtering
- In both the news page and the admin database, I wanted to ensure effortless searching for news articles or user profiles. Users and administrators can initiate a search by typing in a search bar, with results displayed in real-time. When the search input is cleared, the list should revert to the full set of users or news articles.
- Being new to this task, I carried out some research and determined that a filter function was the most suitable solution. This function would filter results based on the user's input. To enable this search, I stored the list in the application's state and targetted properties containing matching letters. I also learned to manage the reset functionality by establishing an additional state that reverts to the full list when the input is empty, ensuring a smooth experience for resetting search results.