Cozy Place is a fullstack application that provides a virtual desk space. It is mainly targetted towards those studying computer science, but can be enjoyed by anyone looking for a cozy productivity app!
Current features include:
- Login/Create account form with authentication throughout the app
- Home page with access to weather by city
- Algorithm to do list
- Basic Calculator and Text Area to work through problems
- Garden app which tracks time studied and grows a tree if you study for a specified duration
- Music page connected to Spotify through Spotify Web API
Click Here to Learn How to Try Cozy Place
This section includes all of the features of Cozy Place with demos and explanations of the technology used
Webpack was used to bundle frontend assets and proxy requests to the server. Webpack was chosen for it's large plugin ecosystem and highly tunable configuration. The current configuration has hot module reloading enabled for enhanced developer experience.
Frontend: The frontend was built using React, JavaScript, HTML, & SASS/CSS. React is my JavaScript framework of choice for most projects due to the large amount of community support, vast library ecosystem, and use of a virtual DOM to make fast and efficient updates to the DOM. One major library used in this project is react-router-dom, which is used to handle routes to different 'pages' on the website. React-router-dom allows the SPA (single page application) to conditionally render components associated with different routes while minimizing network requests.
Backend: The backend server was built with Node.js/Express using the middleware pattern to enhance readability and debugging ability. All data is stored in a non-relational MongoDB database for quick retrieval of user data and flexible data structuring. This flexibility was useful as the vision for the project changed quickly and data modeling had to be changed frequently.
Screen.Recording.2023-04-04.at.11.54.15.PM.mov
Technology Used: Cozy Place's authentication was built using HTTP Only Cookies and Sessions. Another common method to handle authentication is using JWTs (JSON Web Token), which are often more scalable due to their ability to minimize requests to the server (if stateless), however, Cozy Place was intentionally designed as a small scale project. HTTP only cookies were chosen due to being lightweight, automatically sent with every request to the server (useful for the various requests we make to the server), and fairly secure.
Features: Upon loading the application, users are navigated to the login page. If the user does not yet have an account, they can create an account using the signup form. The user's information is then sent to the server, where the password is encrypted using Bcrypt and their credentials are stored in the database. Finally, the user is navigated back to the login page.
When a user logs in with verified credentials, an HTTP Only cookie with the user id is created and a session tied to the user that lasts 30 minutes is stored in the database. Evertime a user accesses a page, a request is sent to the server and a query is made to the database looking for a session belonging to the user. If the user no longer has a session, the user is alerted and navigated back to the login page. Additionally, users cannot access the Login or Signup pages if they have an active session. They must log out first, which clears their user id cookie and deletes the session from the database.
Screen.Recording.2023-04-05.at.11.44.11.PM.mov
Technology Used: The home page weather app uses the Open Weather API to fetch weather data for a specified city using Axios. Axios is a nice Javascript library that is similar to the Fetch API. I like to incorporate it into my projects because it is less verbose than Fetch API and has robust error handling. OpenWeather has some great free options if you need a weather API for your personal project and is fairly easy to navigate.
Features: Upon logging in the user is greeted with the home page and can enter their city to check the weather! Once the user enters the city, some key weather information is shared with them and a fun image is rendered conditionally depending on the weather.
Screen.Recording.2023-04-05.at.11.44.53.PM.mov
Technology Used: The algorithm page contains a to-do-list with data stored in the NoSQL database for each user. The user interface is updated in sync with updates to the database using useContext and useReducer hooks to manage and update state. Upon loading the page, a useEffect hook is used to fetch the data from the database once and the data is dispatched as a payload to the reducer with an action of 'SET_ALGOS', which sets the algorithms state. This state (an array of algorithm objects) is then mapped onto to-do list items in the UI. When a user creates an algo or updates/deletes an existing algo, the corresponding request is sent to the server to update the data in the database. If this operation is executed successfully (response with status 200), the corresponding action is dispatched to the reducer to update state, which is then reflected in the UI. In small applications useContext and useReducer hooks are great for managing state when the added complexity from a tool like Redux won't give you much benefit. In larger applications, it may make more sense to use a state management tool like Redux to manage complex state interactions.
Features: The algorithms page provides a to-do list for algorithms. Users can add an algorithm with a description to describe an optimal approach to the problem or why they want to revisit a specific problem. If the user enters a valid Leetcode problem as the title, the user can click on the title to open the Leetcode problem page as a new tab. Users can also update and delete their to-do list items. All of the items are tied to the specific user and stored in the database so that data is persisted between sessions.
Screen.Recording.2023-04-06.at.12.01.55.AM.mov
Technology Used: The calculator on this page was built by appending to a string when a calculator button is pressed. When the delete button is pressed, the last element is popped from the string and when the AC button is pressed, the string is reset to an empty string. There are conditional statements to check for invalid inputs like back-to-back operators (e.g '++'), in which case nothing is added to the string. The Eval method is used to evaluate the string. Please note that using Eval can be dangerous as it can allow attackers to inject malicious code into your program, known as code injection or remote code execution. It ca also make it difficult to optimize and debug your code since it creates new scope and variable bindings dynamically at runtime. This can lead to performance issues and hard-to-debug errors. Because the calculator is very simple and the user does not manually input something (the user is limited by the buttons on the calculator to build out the string), this is a lower risk use case for Eval. If you want to implement Eval() in your code, just be sure to think about the potential security and performance implications it might have.
Features: This page allows users to sketch out their ideas for coding problems like algorithms. Users can pseudocode on the notepad and use the calculator on the right to help with basic arithmetic.
Screen.Recording.2023-04-05.at.11.48.14.PM.mov
Technology Used: The garden page uses the same approach as the algorithm page for updating the page in sync with the database using react useContext and useReducer hooks. Read above if you are interested in that aspect of this page! The timer was implemented with useState and useEffect hooks! A count state was initialized with useState and a useEffect dependant on the count state. Within the useEffect scope, an interval is set using setInterval, to decrement the counter by 1 every second. We need the useEffect in order to 'clean up' the interval later, otherwise it would run indefinitely. We have a clean up function inside of the useEffect to clear the interval once the component unmounts or when the count changes.
Features: The garden page is a focus app that tracks a user's total study time and trees planted. Trees are planted when a user stays focussed for a specified amount of time (based on the user's input).
Screen.Recording.2023-04-05.at.11.49.52.PM.mov
Screen.Recording.2023-04-05.at.11.59.13.PM.mov
Technology Used: The first component of this page is the login page. Authorization was handled using the Authorization Code Flow, which is detailed extensively in Spotify's documentation of the API here . Two of my favorite libraries for working with the Spotify Web API are Spotify-Web-API-Node and React-Spotify-Web-Playback . I would definitely check both of those libraries out if you plan on working with the Spotify Web API!
Features: The music page provides a music player that is linked to Spotify. Users can search for songs and play them using the web player or choose to listen through another device. Users can also like songs and it will be added to their liked songs playlist on Spotify.
Cozy Place is not currently hosted, fork and clone this repository to your local machine to get started. Once you have a copy of this repository on your local machine, follow these steps:
- Install dependencies in the root, Frontend, and Backend directories
- Create a new file named '.env' in the root directory. Inside of this file, declare two variables:
- PORT = 4000
- MONGO_URI = [Your Mongo URI]
- Note: You will need to have your own MongoDB database, get started here: https://www.mongodb.com/
- Run the script 'npm run dev' in your terminal
- Have fun studying!