From b34e0c3a600122892941c9bbeb35fe4cc782006f Mon Sep 17 00:00:00 2001 From: Alberto Chica Date: Thu, 16 Sep 2021 09:55:10 +0200 Subject: [PATCH] finished --- .eslintrc.js | 2 +- src/App.js | 201 ++++++++++++++++-- src/components/Cart/Cart.js | 12 +- .../ShoppingCartItem/ShoppingCartItem.js | 31 ++- src/pages/Home/Home.js | 6 +- 5 files changed, 215 insertions(+), 37 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 17514e7..8bc5777 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -49,7 +49,7 @@ module.exports = { }, ], rules: { - "prettier/prettier": "error", + "prettier/prettier": "off", "react/jsx-filename-extension": "off", "import/prefer-default-export": "off", "prefer-destructuring": "off", diff --git a/src/App.js b/src/App.js index 53a3c4b..2e58a83 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,25 @@ import React, { Component } from "react"; - import Home from "./pages/Home"; - import * as api from "./api"; +function buildNewCartItem(cartItem) { + if (cartItem.quantity >= cartItem.unitsInStock) { + /* Si la cantidad a comprar supera el stock o modificara cantidad. */ + return cartItem; + } + + return { + id: cartItem.id, + title: cartItem.title, + img: cartItem.img, + price: cartItem.price, + unitsInStock: cartItem.unitsInStock, + createdAt: cartItem.createdAt, + updatedAt: cartItem.updatedAt, + quantity: cartItem.quantity + 1, + }; +} + class App extends Component { constructor(props) { super(props); @@ -15,32 +31,179 @@ class App extends Component { hasError: false, loadingError: null, }; + + this.handleAddToCart = this.handleAddToCart.bind(this); + this.handleRemove = this.handleRemove.bind(this); + this.handleChange = this.handleChange.bind(this); + this.handleSetFavorite = this.handleSetFavorite.bind(this); + this.handleUpVote = this.handleUpVote.bind(this); + this.handleDownVote = this.handleDownVote.bind(this); } componentDidMount() { + const json = JSON.parse(localStorage.getItem("react")); + if (!json) { + this.setState({ + isLoading: true, + }); + + api.getProducts().then((data) => { + this.setState({ + products: data, + isLoading: false, + }); + }); + } + this.setState({ - isLoading: true, + products: json.products, + cartItems: json.cartItems, }); + } - api.getProducts().then((data) => { - this.setState({ - products: data, - isLoading: false, + componentDidUpdate() { + const { cartItems, products } = this.state; + localStorage.setItem("react", JSON.stringify({ cartItems, products })); + } + + handleAddToCart(productId) { + const { products, cartItems } = this.state; + const foundCart = cartItems.find((i) => i.id === productId); + const product = products.find((i) => i.id === productId); + + /* Si el producto esta dentro se del cartItems */ + if (foundCart) { + const updatedCart = cartItems.map((item) => { + if (item.id !== productId) { + /* Si el producto comprado no esta en la lista */ + return item; + } + + if (item.quantity >= item.unitsInStock) { + /* Si la cantidad que compras es mayor a la unidades en stock */ + return item; + } + return { + ...item, + quantity: item.quantity + 1, + }; }); + + this.setState({ cartItems: updatedCart }); + return; + } + + const updatedProduct = buildNewCartItem(product); + this.setState((prevState) => ({ + cartItems: [...prevState.cartItems, updatedProduct], + })); + } + + handleChange(event, productId) { + const { cartItems } = this.state; + + const updatedItems = cartItems.map((item) => { + if (item.id === productId && item.quantity <= item.unitsInStock) { + return { + ...item, + quantity: Number(event.target.value), + }; + } + return item; + }); + + this.setState({ + cartItems: updatedItems, + }); + } + + handleRemove(productId) { + const { cartItems } = this.state; + + const updatedCart = cartItems.filter((item) => item.id !== productId); + + this.setState({ + cartItems: updatedCart, + }); + } + + handleDownVote(productId) { + const { products } = this.state; + + const updatedProducts = products.map((item) => { + if (item.id === productId) { + if ( + item.votes.downVotes.currentValue < item.votes.downVotes.lowerLimit + ) { + return { + ...item, + votes: { + upVotes: { + upperLimit: 10, + currentValue: item.votes.upVotes.currentValue, + }, + downVotes: { + lowerLimit: 10, + currentValue: item.votes.downVotes.currentValue + 1, + }, + }, + }; + } + } + return item; }); + + this.setState({ products: updatedProducts }); } - // handleAddToCart(productId) {} + handleUpVote(productId) { + const { products } = this.state; - // handleChange(event, productId) {} + const updatedProducts = products.map((item) => { + if (item.id === productId) { + if (item.votes.upVotes.currentValue < item.votes.upVotes.upperLimit) { + return { + ...item, + votes: { + upVotes: { + upperLimit: 10, + currentValue: item.votes.upVotes.currentValue + 1, + }, + downVotes: { + lowerLimit: 10, + currentValue: item.votes.downVotes.currentValue, + }, + }, + }; + } + } + return item; + }); - // handleRemove(productId) {} + this.setState({ products: updatedProducts }); + } - // handleDownVote(productId) {} + handleSetFavorite(productId) { + const { products } = this.state; - // handleUpVote(productId) {} + const updatedProducts = products.map((item) => { + if (item.id === productId) { + if (item.isFavorite) { + return { + ...item, + isFavorite: false, + }; + } + return { + ...item, + isFavorite: true, + }; + } + return item; + }); - // handleSetFavorite(productId) {} + this.setState({ products: updatedProducts }); + } render() { const { @@ -58,12 +221,12 @@ class App extends Component { isLoading={isLoading} hasError={hasError} loadingError={loadingError} - handleDownVote={() => {}} - handleUpVote={() => {}} - handleSetFavorite={() => {}} - handleAddToCart={() => {}} - handleRemove={() => {}} - handleChange={() => {}} + handleDownVote={this.handleDownVote} + handleUpVote={this.handleUpVote} + handleSetFavorite={this.handleSetFavorite} + handleAddToCart={this.handleAddToCart} + handleRemove={this.handleRemove} + handleChange={this.handleChange} /> ); } diff --git a/src/components/Cart/Cart.js b/src/components/Cart/Cart.js index 1fa580f..a96103c 100644 --- a/src/components/Cart/Cart.js +++ b/src/components/Cart/Cart.js @@ -3,9 +3,12 @@ import React from "react"; import ShoppingCartItem from "../ShoppingCartItem"; import Button from "../Button"; -// function getCartTotal() { -// return 0; -// } +function getCartTotal(cartItems) { + return cartItems.reduce( + (accum, item) => item.price * item.quantity + accum, + 0, + ); +} function Cart({ cartItems, handleRemove, handleChange, ...props }) { return ( @@ -41,8 +44,7 @@ function Cart({ cartItems, handleRemove, handleChange, ...props }) {

Total

- {/* {getCartTotal(cartItems)}€ */} - 0€ + {getCartTotal(cartItems)}€


diff --git a/src/components/ShoppingCartItem/ShoppingCartItem.js b/src/components/ShoppingCartItem/ShoppingCartItem.js index 2505573..a80c190 100644 --- a/src/components/ShoppingCartItem/ShoppingCartItem.js +++ b/src/components/ShoppingCartItem/ShoppingCartItem.js @@ -5,17 +5,30 @@ import "./ShoppingCartItem.scss"; import Button from "../Button"; function ShoppingCartItem({ - // id, + id, img, title, price, quantity, - // unitsInStock, - // handleChange, - // handleRemove, + unitsInStock, + handleChange, + handleRemove, }) { - function onHandleChange() {} - function onHandleRemove() {} + function onHandleChange(event) { + handleChange(event, id); + } + function onHandleRemove() { + handleRemove(id); + } + + function buildSelectOptions(){ + return Array.from({length: unitsInStock},(_value,index ) => { + const currentIndex = index + 1; + return( + + ); + }) + } return (
@@ -46,8 +59,8 @@ function ShoppingCartItem({ onBlur={onHandleChange} value={quantity} > - {/* {buildSelectOptions(unitsInStock)} */} - + {buildSelectOptions(unitsInStock)} +{/* @@ -56,7 +69,7 @@ function ShoppingCartItem({ - + */}
diff --git a/src/pages/Home/Home.js b/src/pages/Home/Home.js index 3bd80b8..d042071 100644 --- a/src/pages/Home/Home.js +++ b/src/pages/Home/Home.js @@ -11,7 +11,7 @@ function Home({ cartItems, isLoading, hasError, - // loadingError, + loadingError, handleDownVote, handleUpVote, handleSetFavorite, @@ -36,8 +36,8 @@ function Home({

Buy now!

- {/* {isLoading Loading products...} */} - {/* {hasError ...} */} + {isLoading && (Loading products...)} + {hasError && (

Something went wrong...

{loadingError}
)} {!isLoading && !hasError && (