Build a shopping cart that has the following functionality using this dummy API http://next.json-generator.com/api/json/get/4kiDK7gxZ:
- Show a grid of items with each item has price, thumbnail & "add to cart" button.
- Clicking one item should show more info about the item (description, price, remaining stock & add to cart button).
- When you click the add to cart button the item should be added to the cart and the stock number should be updated in the detail view of the item.
- The cart should have a checkout button, when clicked show a successful message and clear the cart.
- Design is left for you, it's not a design task so nothing fancy, but of course responsive. Functionality is more important.
Please provide a
README
file describing your rational, tools & ideas you used and why. Use git (github, gitlab or bitbucket repo) if possible, but if you can't provide a git repo somewhere make sure you send a zip file with the.git
folder included.
$ git clone [email protected]:Marfru/lightspeed.git
$ cd lightspeed
$ npm i
$ npm start
You need to have an .env in the root since I have used a custom-react-scripts package to support decorators and scss files with ease. The env files enable decorators (mobx) and scss/sass support. It should be included in the repo, but:
REACT_APP_DECORATORS=true
REACT_APP_SASS_MODULES=true
REACT_APP_SASS=true
You will have some experimental decorators warnings. Only warnings, it still compiles with no problem, but I know it can be annoying. Just create a tsconfig.json file in the root of the directory with this content:
{
"compilerOptions": {
"experimentalDecorators": true,
"allowJs": true
}
}
Package | Url |
---|---|
mobx | https://www.npmjs.com/package/mobx |
mobx-react | https://www.npmjs.com/package/mobx-react |
axios | https://www.npmjs.com/package/axios |
react-router-dom | https://www.npmjs.com/package/react-router-dom |
Custom-React-Scripts | https://www.npmjs.com/package/custom-react-scripts |
I used mobx and its decorators to build this small shopping cart with basic functionality. I decided to use mobx since I have used it in the past, and for a fast assignment, it was my preferred choice. In my personal opinion, it's also a bit more readable.
Actions like adding products to the cart or calculating the total amount of the cart that are being occurred in this app, are located in src/stores/CartStore.js A problem I encountered, was that the json data from {product.price}, had a ',' when it was larger than $999. Decided to replace the comma with an empty string, with a parseFloat included in the product price.
Fetching API using axios is done in src/stores/ProductStore.js
In the components folder, we have a common folder which has a re-usable Modal.js and Success.js implemented in other components.
In the styles folder, we have basic .scss files with variables, media queries (responsiveness, a basic one) and other styling values.
In Home.js I render:
- Cart.js => Renders the products added to your cart, and the total sum of it. Also, the ability to remove products.
- ProductList.js => Renders the fetched data from the API. And yes, I used tables.
- ItemsCount.js => Renders the quantity of items in the shopping cart.
Stores:
- CartStore.js => The sum of the total amount of products in the cart is done here. Also actions such as pushing products to the cart, emptying and removing products.
- ProductStore.js => Using axios I fetch the API, so I can inject it (thanks to mobx's decorators) in Components such as ProductList
Rest of components:
- Cart.js => Renders the content of the shopping cart which includes: Added products, Total Amount to be paid, and a checkout button which clears the shopping cart's content.
- CartItem.js => Single products added to the shopping cart that are also removable. This is imported in cart.js.
- MoreInfo.js => Renders the content of the modal when the users clicks on the "More Info" button on the main overview of the products (grid).
- ProductList.js => Renders the grid of products.
- ProductSingle.js => Rendering individual products where fetching data is being done by ProductStore.js.
Nothing much to add here. Used tables with light colours, and Roboto font just to make it look a bit more smooth.
The media queries variables (located in components/styles/_vars.scss) are being applied to the table and main wrapper only. Which still makes it responsive, but it can be worked on a lot.
- As mentioned before, rendering the price and calculating the total wasn't working as expected. Until I found the solution to replace the ',' to an empty string.
- Decorators were not being supported. I used Custom React Scripts (https://www.npmjs.com/package/custom-react-scripts) with the custom .env file mentioned above.
- Didn't have time to render the modal component Success.js on the OnClick function located on the Checkout Button in the shopping cart. But I know how to do it. I just added an alert, and when accepted, it clears the shopping cart.
- I'm more comfortable using Styled Components (or Emotion), but a basic design using SASS was faster.
- Folders should be more organized:
├── components
│ ├── App.js
│ ├── Cart.js
│ ├── CartItem.js
│ ├── Checkout.js
│ ├── Home.js
│ ├── ItemsCount.js
│ ├── MoreInfo.js
│ ├── ProductList.js
│ ├── ProductSingle.js
│ ├── common
│ │ ├── Modal.js
│ │ └── Success.js
│ └── styles
│ ├── _main.scss
│ ├── _vars.scss
│ └── background.svg
├── index.js
├── serviceWorker.js
└── stores
├── CartStore.js
├── ProductStore.js
└── index.js