#react.js #master-in-software-engineering
In this project you will learn how to create a React.js and how to apply all the important concepts.
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.
See deployment for notes on how to deploy the project on a live system.
First, you will need to clone or fork the repository into your Github
account:
$ git clone https://github.com/assembler-school/react-shopping-cart-state.git
The repository is made up of several branches that include the contents of each section.
The branches follow a naming strategy like the following:
main: includes the main contents and the instructionsassembler-solution: includes the solution
In order to fetch all the remote branches in the repository, you can use the following command:
$ git fetch --all$ git branch --allThen, you can create a local branch based on a remote branch with the following command:
$ git checkout -b <new_branch_name> <remote_branch_name>First, you will need to install the dependencies with: npm install.
Run the following command in your terminal after cloning the main repo:
$ npm installThe tests that validate your solution can be executed by running the following command:
$ npm run test
In the assembler-solution branch you can see an implementation of these tools
if you'd like to use them.
In this pill we won't deploy the app.
React.js@testing-library/reacteslintprettierlint-stagedhusky
This is an overview of the main requirements of this project. The exact ones are found in the doc that the academic team will provide you.
- You must follow all the instructions of the project step-by-step
- You should always try to solve them by yourself before asking for help
- You should always help your team members and fellow students of the master so that you can all learn together and become better software developers and team members
- You must finish all the steps that are marked as
Required - You must use semantic HTML5 elements for all the markup of the application
- Once you are done, you can move on to the optional ones that are marked as
Extra π―
/src/App.jsIn this step you will need to call the api.getProducts() method inside the
componentDidMount() lifecycle method and store the data in state.
This method returns the products that the app needs. Therefore, you will need to
call setState({products: apiProducts}) once the promise is finished.
@TODO
/src/pages/Home.jsIn this step you will have to:
- render a text of
Loading products...when theisLoadingprop istrue - render:
<h2>Something went wrong...</h2>when thehasErrorprop istrue- and the error message it self:
<pre><code>{loadingError}</code></pre>
@TODO
/src/App.jsIn this step you will have to be able to add elements to the cart:
For this, you will need to complete the code of the
handleAddToCart(productId) {} method in the App component so that:
It searches if the state.cartItems has a product with the productId
- if it finds it, it will have to increment the quantity of the item without adding a new element to the cart, just increment the quantity of the existing one
- if it doesn't find it, it will have to copy the product from the
state.productsproperty and create a new cart item in thestate.cartItemsproperty with the following keys:idtitleimgpriceunitsInStockcreatedAtupdatedAtquantity- furthermore, when creating the new cart item its quantity will have to be incremented by 1
@hint: thecreatedAtandupdatedAtvalues can be created with:new Date().toISOString()
- Check if the
item.quantity >= item.unitsInStockso that users cannot add items to the cart if the currentquantityis greater or equal to theunitsInStock
{
"cartItems": [
{
"id": "fbabb4ce-823f-5790-9b87-35819d4be380",
"title": "Puma 80's",
"img": "/static/media/img2.2e6236fd.jpeg",
"price": 109,
"unitsInStock": 5,
"createdAt": "2021-04-23T09:12:24.2424+02",
"updatedAt": "2021-04-23T09:12:24.2424+02",
"quantity": 2
},
{
"id": "65d6b269-209b-50ac-a566-ca6a334aa6f0",
"title": "Nike Runner 2000",
"img": "/static/media/img1.a79d9fb0.jpeg",
"price": 88,
"unitsInStock": 5,
"createdAt": "2021-04-23T09:12:24.2424+02",
"updatedAt": "2021-04-23T09:12:24.2424+02",
"quantity": 4
}
],
"products": [
{
"id": "65d6b269-209b-50ac-a566-ca6a334aa6f0",
"title": "Nike Runner 2000",
"price": 88,
"img": "/static/media/img1.a79d9fb0.jpeg",
"shortDescription": "Ipsum sint consequat culpa adipisicing occaecat aliquip aliquip sit labore aute.",
"longDescription": "Occaecat nostrud ipsum excepteur adipisicing dolor. Deserunt pariatur commodo duis Lorem laboris irure dolor dolor proident aute pariatur. Nostrud consectetur labore anim est deserunt esse est nostrud ipsum velit incididunt aliqua anim. Occaecat exercitation culpa proident aute aliqua exercitation nulla cillum velit nisi reprehenderit Lorem sunt.",
"isFavorite": true,
"createdAt": "2021-04-23T09:12:24.2424+02",
"updatedAt": "2021-04-23T09:12:24.2424+02",
"unitsInStock": 5,
"quantity": 0,
"votes": {
"upVotes": {
"upperLimit": 10,
"currentValue": 7
},
"downVotes": {
"lowerLimit": 10,
"currentValue": 6
}
},
"author": {
"id": "9cb107d1-cc36-5399-a8b2-0ad65daa5d36",
"firstName": "Clyde",
"lastName": "Tucker",
"email": "mepsukjid@riz.jm"
}
},
{
"id": "fbabb4ce-823f-5790-9b87-35819d4be380",
"title": "Puma 80's",
"price": 109,
"img": "/static/media/img2.2e6236fd.jpeg",
"shortDescription": "Ea nisi minim cillum quis enim ullamco enim sint.",
"longDescription": "Eu in voluptate ut magna id sint elit est enim et officia. Lorem id commodo duis dolor ullamco consequat dolor culpa. Irure nostrud veniam nulla enim occaecat nostrud ullamco sunt. Excepteur esse occaecat cupidatat excepteur adipisicing fugiat cillum amet do ad aliqua.",
"isFavorite": true,
"createdAt": "2021-04-23T09:12:24.2424+02",
"updatedAt": "2021-04-23T09:12:24.2424+02",
"unitsInStock": 5,
"quantity": 0,
"votes": {
"upVotes": {
"upperLimit": 10,
"currentValue": 2
},
"downVotes": {
"lowerLimit": 10,
"currentValue": 0
}
},
"author": {
"id": "b2c1f67d-91ee-5a62-b198-4229a4ecc0b8",
"firstName": "Aaron",
"lastName": "Casey",
"email": "mascefjuh@rekos.pl"
}
}
]
}@TODO
/src/App.jsIn this step you will have to be able to remove elements from the cart:
For this, you will need to complete the code of the handleRemove(productId) {}
method in the App component so that it removes the cartItem that has the
productId that the method receives.
@TODO
/src/components/CartIn this step you will have to be able to show to cart total based on the items
in the cart (state.cartItems).
You can do this with any loop in javascript but we recommend using
[].reduce().
- <strong>0β¬</strong>
+ <strong>{getCartTotal(cartItems)}β¬</strong>-// function getCartTotal() {
-// return 0;
-// }
+function getCartTotal(cart) {
+ return cart.reduce((accum, item) => { ... }, 0);
+}@TODO
/src/App.jsIn this step you will have to be able to update the quantity of elements in the
cart using a select element.
For this, you will need to complete the code of the
handleChange(event, productId) {} method in the App component so that:
It finds the cartItem that has the productId from the state.cartItems
property and increment the quantity by 1 if the
item.quantity <= item.unitsInStock.
- In the
<ShoppingCartItem />component check the value of theunitsInStockproperty of thecartItemand create as many<option>child elements of the<select>element as there areunitsInStock.
Example
unitsInStock: 3
<select
className="custom-select"
onChange={onHandleChange}
onBlur={onHandleChange}
value={quantity}
>
<option value="1,">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>Can be created with:
function buildSelectOptions(unitsInStock) {
return Array.from({ length: unitsInStock }, (_value, index) => {
const currentIndex = index + 1;
return (
// <option ...>...</option>
);
});
}
<select
className="custom-select"
onChange={onHandleChange}
onBlur={onHandleChange}
value={quantity}
>
{buildSelectOptions(unitsInStock)}
</select>;@TODO
/src/App.jsIn this step you will have to be able to mark an element as favorite by clicking
on the <FavoriteIconButton /> in the <ItemCard /> component.
For this you will have to complete the code of the
handleSetFavorite(productId) method in the App.js component.
@TODO
/src/App.jsIn this step you will have to be able to up vote a product by clicking on
the <IconButton /> in the <ItemCard /> component that has the onUpVote
prop.
For this you will have to complete the code of the handleUpVote(productId)
method in the App.js component so that:
- if:
product.votes.upVotes.currentValue < product.votes.upVotes.upperLimit- then:
product.votes.upVotes.currentValue + 1
- then:
- else:
return product
/src/App.jsIn this step you will have to be able to down vote a product by clicking on
the <IconButton /> in the <ItemCard /> component that has the onUpVote
prop.
For this you will have to complete the code of the handleUpVote(productId)
method in the App.js component so that:
- if:
product.votes.downVotes.currentValue < product.votes.downVotes.lowerLimit- then:
product.votes.downVotes.currentValue + 1
- then:
- else:
return product
@TODO
/src/App.jsIn this step you will have to be able to read from localStorage the state data
in componentDidMount() and update the localStorage data when the state is
updated in componentDidUpdate().
@TODO
To deliver this project you must follow the steps indicated in the document:
This project is licensed under the MIT License - see the LICENSE file for details
Thanks goes to these wonderful people (emoji key):
Dani Lucaci π» π π‘ π§ |
This project follows the all-contributors specification. Contributions of any kind welcome!
