Project 4: Cloud9 Scents ☁️

This is the fourth and last project associated with the General Assembly Software Engineering Flex course. I decided to go solo and develop a Full Stack app to showcase a perfume gallery where users can see and create fragrances.

Deployed at Cloud9 Scents
Backend code can be found here

Table of contents

  1. How it works
  2. Build
  3. Styling
  4. Challenges and Wins
  5. Key Learnings
  6. Future Improvements

Tech stack

This time the backend was developed using Python with a Django REST framework that utilises a PostgreSQL database. As for the client side, I once again used React but decided to venture out with Material UI for the styling.

How it works

The concept of this project is to allow users to access it as their fragrance wardrobe where they can see any fragrance and even create their own fictional scent. This enables them to explore the perfume world in more depth by getting to know a variety of brands and notes of the scents.

Build

Solo project | Timeframe: 2 weeks

Planning

I started off with designing the relationship models I would use in my backend with QuickDBD.

Screenshot 2022-05-04 at 13 24 38

This really helped put into perspective what models I would really need for the app and their one-to-one, many-to-one or many-to-many relationships. Although I stayed on track for most of it, I discarded the notes model as it didn't really need to be separate - I just put it down as a part of the Fragrance model. I also did not include the comments, should I have had more time this is something I would have liked to implement.

In terms of wireframing, I used Excalidraw to visualise what my app would roughly look like.

Planning didn't take that long, however the original idea I had in mind was for the app to be a perfume gallery where fragrances are displayed. As I was doing the models relationships and wireframing, I realised I didn't really have any functionality between them. Therefore, I had to slightly adjust the concept and allow users to create their own scents too. This way I would be able to explore relationships between at least 2 models.

Development

Backend

Compared to my previous project, using Django framework for the backend was quite challenging. It definitely has a higher complexity and I did struggle at times. I spent 90% of the project time on my Backend as I kept on having challenges. I finally implemented basic permissions and authorisation for instance, to check whether the user logged in is the creator of that specific fragrance in order to amend it.

This was done by implementing a creator foreign key to the Perfume model.

Screenshot 2022-06-10 at 12 55 25

I grabbed the request.user to get the id of the user logged in and assigned it to the perfume.creator. After saving it, that specific perfume would have been created by that specific user.

Screenshot 2022-06-10 at 12 54 48

Back in permissions.py, my app undertakes a check to confirm the identity of the user. If they are the creator of the fragrance, they will be able to amend it. Once again, this is done by comparing the request.user to the perfume.creator.

Screenshot 2022-06-10 at 12 55 10

Frontend

As most part of the time was spent on Backend, I was left with quite a time restraint to create the client interface. I started off with the Login and Register pages. When the user tries to register, their data is grabbed by the form data and added to the database through a POST request.

Screenshot 2022-06-10 at 13 10 27

Once they are successfully registered, they will be taken to the Login portal.

Screenshot 2022-06-10 at 13 11 23

The app performs a post request to the api/token endpoint where they can obtain a JWT token to access all the features that require authorisation, by doing this we are able to authenticate the user. This gets stored in LocalStorage so it is easily accessible.

Styling

With all my previous projects, I have been using classic CSS therefore I wanted to challenge myself and use a styling library this time. Learning a new styling library can be quite time consuming to get the ins and outs of how it works, nonetheless I decided to go for it and chose MaterialUI. I didn't really spend too much time looking at the docs on how to use it, I sort of learnt it as I went along and according to what features I wanted to implement.

I felt like I needed a break from coding logic and I'm normally quite confident in it so I decided to start working on the styling. After playing around with it for a while, I was really proud of the Login and Register pages as well as the Homepage.

Initially I struggled with how to style components and what the terminology for each is but soon it all made sense. I used the withRoot component which applies the same styling to the whole page without having to recode it.

This can be easily done by wrapping the specific component around withRoot() eg:

Screenshot 2022-06-10 at 13 32 38

Challenges and Wins

This time around I found the challenge and wins were quite 50-50. Definitely found the Django framework quite complex compared to previous ones I have used. The terminology and syntax were quite difficult to grasp compared to previous frameworks. There is so much to keep track of when initially setting up a project with Django that I got confused at times.

On a brighter note, I am very pleased with the styling achieved in such little amount of time. Using a syling library was a challenge I wanted to take. Although the concepts were new and sometimes not always the most intuitive, I really enjoyed using MaterialUI.

Key Learnings

One of the major key learnings I will take from this project is definitely not spending an unreasonable amount of time dwelling on bugs and rather move on and take a break. I should have split my time wisely so I would complete all the functionality I intended. As it stands now, my project didn't meet all the functionality I once had in mind when planning. It can be quite challenging to meet all these expectations in such a short timeframe. If I had allowed more time for my Frontend, I would've got a lot more logic done.

However, I also challenged myself to learn at the last minute a styling library which is quite complex and succeeded. Working with one on this project was one of my goals and the end result is very pleasing. I tend to focus more on JavaScript/React coding rather than styling, so this was a change.

Future Improvements

Features to add:

  • Individual perfume page
  • Comments section on each perfume
  • Individual profile page

Bugs to be fixed:

  • Fetching information of an individual Perfume in order to open an individual page based on the ID clicked
  • IsPremium permission to allow users to create more than 1 scent